【问题标题】:Backbone template loading using promises使用 Promise 加载主干模板
【发布时间】:2015-08-19 16:58:51
【问题描述】:

类似于this question,我正在寻找一种通过 Javascript 承诺加载模板的方法。我遇到的问题是将编译后的模板返回到主干视图。注意: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);
  });
}

在视图的initialize 中,我有一个监听器设置为

initialize: function() {
  this.model.on('change', this.render, this);
}

从服务器获取数据时按预期触发。

问题出在render函数执行的时候

render: function() {
  ...
  this.$el.html(this.template(attributes));
  ...
}

没有任何东西像我期望的那样呈现给 html。我确定我在模板承诺回调中遗漏了一些简单的东西,但是无论我更改什么,html 都不会呈现,也不会出现错误。

【问题讨论】:

  • 另一个问题的答案有什么问题?你只需要修改你的代码,让template 得到一个回调函数(或返回一个promise)而不是试图返回一个值。
  • @muistooshort 另一个问题是关于他们如何返回模板并将其应用于渲染方法的模糊,这就是我的问题。除了Promise 之外,manager 是什么?tpl 如何从Handlebars.compile 传递到回调中?在这一点上,我对 js promises 的经验和知识是有限的。
  • 您不会从您的 template 函数中返回任何内容,而是给它一个函数,以便在 AJAX 调用完成时调用它:this.template('template_name', function(tmpl) { /* do things with tmpl here */ })
  • @muistooshort 使用您的 cmets 帮助解决了这个问题。谢谢!

标签: javascript templates backbone.js handlebars.js


【解决方案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...,将返回承诺,然后将使用已编译的值(属性)进行解析。

那么你的渲染函数可能是:

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 文件中。我所做的是使用 JS 模板文件

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

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

【讨论】:

  • 很好的答案感谢您的帮助!实际上,我昨天使用与您类似的方法解决了这个问题,除了我在构造函数(我正在使用 TypeScript)或初始化程序中运行 promise 并将 this.template 设置为其中的已编译 hbs 文件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多