使用承诺的骨干模板加载

时间:2015-08-19 16:58:51

标签: javascript templates backbone.js handlebars.js

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都不会渲染,也不会出现错误。

1 个答案:

答案 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));
}

在我看来,这更容易处理,在客户端更快,因为您不必在客户端获取文件。