Ember.js使用外部handlebars模板

6
所以,我对Ember.js还比较陌生,已经卡了几个小时了。 我正在使用bloggr客户端进行实验,并希望从外部文件加载那些handlebars模板。
当用户在面板中单击关于页面时,“about”模板应该呈现出来。 这是简短的代码,所以您不必深入挖掘(我相信对于有经验的用户来说很容易)。
在示例中,将模板放在html文件内。
<script type="text/x-handlebars" id="about">
<div class='about'>
  <p>Some text to be shown when users click ABOUT.</p>
</div>

现在我所做的是将x-handlebar代码从html页面中移除,并将其放置在hbs/about.hbs文件中(不包括<script type...>)。现在,在html页面内,我进行了如下处理。

$.ajax({
    url: 'hbs/about.hbs',         
    async: false,
    success: function (resp) {
      App.About = Ember.View.extend({
        template: Ember.Handlebars.compile(resp),
      });
    }         
  });

ajax的结果保存了.hbs页面的内容,然后我必须编译它以便Ember可以渲染它,对吗?我想这就是我所做的。但这是我所能做到的。我所做的对吗?下一步该怎么办?我相信我必须将ajax调用的内容附加到body或其他地方。

提前感谢,我在搜索了SO之后仍然无法使其运行。


顺便说一下,我建议使用Yeoman和generator-ember来搭建项目。这是Ember的一个很好的起点,可以让你立即开始项目,而不是进行这种配置练习。您希望最终产品以尽可能少的请求和尽快的速度完成。像这样程序化地检索模板不会有很好的表现。您可以使用Yeoman获得linting和minification。http://yeoman.io/ - Steve H.
1个回答

12
你可以简单地将模板附加到可用模板的对象上,例如:
Ember.TEMPLATES.cow = Ember.Handlebars.compile("I'm a cow {{log this}}");

或许在你的情况下,应该像这样做:
var url = 'hbs/about.hbs',
    templateName = url.replace('.hbs', '');

Ember.$.ajax({
  url: url,         
  async: false,
  success: function (resp) {
    Em.TEMPLATES[templateName] = Ember.Handlebars.compile(resp);
  }         
});

这是一个应用程序准备好后的懒惰示例:http://emberjs.jsbin.com/apIRef/1/edit 老实说,事先预编译模板(服务器端)对最终用户更具性能优势。
预编译将原始handlebars转换为大量用于构建视图的javascript语句。
当DOM准备好之后,Ember会扫描类型为"text/x-handlebars"的脚本元素,并在其内容上调用编译。然后,它将结果添加到Ember.TEMPLATES对象中,名称来自data-template-name属性。这可能会增加一些完全不必要的加载时间到应用程序中。
例如,当我们提交"I'm a cow {{log this}}"时,它被转换为以下javascript方法。
function anonymous(Handlebars,depth0,helpers,partials,data /**/) {
  this.compilerInfo = [4,'>= 1.0.0'];
  helpers = this.merge(helpers, Ember.Handlebars.helpers); data = data || {};
  var buffer = '', hashTypes, hashContexts, escapeExpression=this.escapeExpression;

  data.buffer.push("I'm a cow ");
  hashTypes = {};
  hashContexts = {};
  data.buffer.push(escapeExpression(helpers.log.call(depth0, "", {hash:{},contexts:[depth0],types:["ID"],hashContexts:hashContexts,hashTypes:hashTypes,data:data})));
  return buffer;
}

最小化后看起来像这样不美观:

function anonymous(e,t,n,r,i){this.compilerInfo=[4,">= 1.0.0"];n=this.merge(n,Ember.Handlebars.helpers);i=i||{};var s="",o,u,a=this.escapeExpression;i.buffer.push("I'm a cow ");o={};u={};i.buffer.push(a(n.log.call(t,"",{hash:{},contexts:[t],types:["ID"],hashContexts:u,hashTypes:o,data:i})));return s}

根据您的后端情况,您可以预先编译和捆绑模板,并将它们发送到html中,以避免在客户端花费时间编译模板。


所以,让我知道我是否理解正确。您预编译了cow模板,并且在单击链接时显示该模板。现在,目标是从另一个文件加载模板,您正在从.compile(code)加载代码。这样,我应该使用一些ajax来获取该文件并检索数据,对吗?我不明白您建议预编译的要点(难道它不总是预编译的吗?)。我在这里试图获得整个画面,抱歉。 - Daniel Sh.
没问题,你想问多少问题都可以!请查看更新后的答案。 - Kingpin2k
太棒了,不仅起作用了,而且还清除了Ember模板中的一些方面。再次感谢。 - Daniel Sh.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接