【发布时间】:2017-07-09 04:59:41
【问题描述】:
我有一个在服务器和客户端上同时使用 Backbone 和 Handlebars 的应用程序。
服务器
Backbone 和 Express-Handlebars 已安装
app.js
app.set('views', path.join(__dirname, '/views'));
app.engine('.hbs', expHbs({
defaultLayout: 'index',
extname: '.hbs'
}));
app.set('view engine', '.hbs');
index.js
exports.init = function(req, res){
res.render('contact/index');
};
index.hbs
<div class="row">
<div class="col-sm-6">
<div class="page-header">
<h1>Send A Message</h1>
</div>
<div id="contact"></div>
</div>
....some code
<script id="tmpl-contact" type="text/x-handlebars-template">
<form>
bootstrap with handlebars temlates {{....}} in here
</form>
</script>
客户
在客户端我通过 Bower 安装了 Backbone 和 Handlebars
在index.js Backbone.view
var Handlebars = require('handlebars');
app.ContactView = Backbone.View.extend({
el: '#contact',
template: Handlebars.compile( $('#tmpl-contact').html() ),
events: {
'submit form': 'preventSubmit',
'click .btn-contact': 'contact'
},
initialize: function() {
this.model = new app.Contact();
this.listenTo(this.model, 'sync', this.render);
this.render();
},
render: function() {
this.$el.html(this.template( this.model.attributes ));
this.$el.find('[name="name"]').focus();
},
preventSubmit: function(event) {
event.preventDefault();
},
contact: function() {
this.$el.find('.btn-contact').attr('disabled', true);
this.model.save({
name: this.$el.find('[name="name"]').val(),
email: this.$el.find('[name="email"]').val(),
message: this.$el.find('[name="message"]').val()
});
}
});
发生的情况是 index.hbs 在服务器端正常渲染,但它没有在脚本内渲染表单;它显示为空的<div id="contact"></div>,并且在控制台中没有显示任何错误。
如Using Handlebars with Backbone 所示,用车把替换下划线模板的一种方法是将_.template 替换为Handlebars.compile,但这些选项都不适用于我。我还为 <script> 尝试了不同的 type 属性,但仍然无法正常工作。
我该如何解决这个问题?任何帮助表示赞赏。谢谢。
在客户端添加了完整的 index.js
/* global app:true */
var Handlebars = require('Нandlebars');
(function() {
'use strict';
app = app || {};
app.Contact = Backbone.Model.extend({
url: '/contact/',
defaults: {
success: false,
errors: [],
errfor: {},
name: '',
email: '',
message: ''
}
});
app.ContactView = Backbone.View.extend({
el: '#contact',
template: Handlebars.compile( $('#tmpl-contact').html() ),
events: {
'submit form': 'preventSubmit',
'click .btn-contact': 'contact'
},
initialize: function() {
this.model = new app.Contact();
this.listenTo(this.model, 'sync', this.render);
this.render();
},
render: function() {
this.$el.html(this.template( this.model.attributes ));
this.$el.find('[name="name"]').focus();
},
preventSubmit: function(event) {
event.preventDefault();
},
contact: function() {
this.$el.find('.btn-contact').attr('disabled', true);
this.model.save({
name: this.$el.find('[name="name"]').val(),
email: this.$el.find('[name="email"]').val(),
message: this.$el.find('[name="message"]').val()
});
}
});
$(document).ready(function() {
app.contactView = new app.ContactView();
});
}());
【问题讨论】:
-
你在哪里初始化
index.js...中的视图?声明一个视图是不够的。您需要在加载所需的内容后对其进行初始化。 -
@T J 如果你的意思是使用 Backbone.Model.Extend,我把它放在同一个文件中
-
(function() { 'use strict'; app = app || {}; app.Contact = Backbone.Model.extend({ url: '/contact/', 默认值: { 成功: false, errors: [], errfor: {}, name: '', email: '', message: '' } }); 这是带有 Jade 和 Underscore 模板的 github.com/jedireza/drywall。我正在尝试将其更改为车把。
-
不,您应该在某处拥有
new app.ContactView()。顺便说一句,如果您要共享代码块,请edit 并添加它。它们在 cmets 中是不可读的 -
$(document).ready(function() { app.contactView = new app.ContactView(); });将初始化视图然后您的应用程序加载。那时index.hbs的内容是否可用?还是稍后加载?
标签: backbone.js handlebars.js express-handlebars