与this question类似,我正在寻找通过Javascript承诺加载模板的方法。我遇到的问题是将已编译的模板返回到Backbone View。注意:this.getFile()
会返回new Promise
,它会按预期获取模板。
template: function(attributes) {
this.getFile('/path/to/template').then(function(tpl) {
var compiled = Handlebars.compile(tpl);
return compiled(attributes);
}, function(error) {
console.error('Failed!', error);
});
}
在View initialize
中,我有一个侦听器设置为
initialize: function() {
this.model.on('change', this.render, this);
}
在从服务器获取数据时按预期触发。
问题是当渲染函数执行行
时render: function() {
...
this.$el.html(this.template(attributes));
...
}
没有像我期望的那样呈现给html。我确定我在模板承诺回调中遗漏了一些简单的东西,但无论我改变什么,html都不会渲染,也不会出现错误。
答案 0 :(得分:1)
像@muistooshort所指出的那样。模板函数不返回任何内容,它只是对另一个函数执行异步调用并处理它。
但是,渲染函数是同步的,它执行模板函数,然后将直接返回的内容添加到$ el。在这种情况下,没有什么可以补充的。
这个问题有两个解决方案。 1.使模板函数返回一个promise。在渲染中,在向$ el添加内容之前等待模板完成。
示例:
template: function(attributes) {
return this.getFile('/path/to/template').then(function(tpl) {
var compiled = Handlebars.compile(tpl);
return compiled(attributes);
});
}
注意这个返回this.getFile ...,将返回promise,然后将使用编译的值(属性)解析。
然后你的渲染功能可能是:
render: function() {
var self=this;
this.template(attributes).then(function(data){
self.$el.html(data);// data is the stuff that was compiled.
})
}
但是,我可以建议您在管理模板方面采用不同的解决方案吗?
作为个人观点,模板(ejs,jade或hbs)在编译时实际上非常小。所以这些数据可以使用require在你的js文件中编译。我所做的是使用JStemplate文件
module.exports={
t1:require(path/to/template1),
t2:require(path/to/template2),
}
然后,在其他骨干视图中查看js文件。我能做到
var allTemplates=require('./JStemplate.js');
...
render:function(){
this.$el.html(allTemplates.t1(attributes));
}
在我看来,这更容易处理,在客户端更快,因为您不必在客户端获取文件。