【问题标题】:Ember.js with external handlebars template带有外部车把模板的 Ember.js
【发布时间】:2013-11-09 01:20:23
【问题描述】:

所以,我对Ember.js 有点陌生,我已经过了几个小时了。我正在玩这个bloggr client,我想要完成的是从外部文件加载那些handlebars 模板。

当用户单击面板中的“关于”页面时,应呈现“关于”模板。 这是简短的代码,因此您不必挖掘那么多(我相信对于有经验的用户来说会很容易)

.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 页面中取出并放置(没有&lt;script type...&gt;),然后将其放入hbs/about.hbs

现在,在 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。 yeoman.io

标签: javascript ajax ember.js handlebars.js


【解决方案1】:

您可以像这样将模板附加到可用模板的对象上:

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

说实话,事先预编译模板(服务器端)对最终用户来说性能更高。

预编译将原始句柄转换为大量 javascript 语句,以在构建视图时使用。

当 DOM 准备就绪时,Ember 会扫描 DOM 以查找类型为“text/x-handlebars”的脚本元素,并在其内容上调用 compile。然后它将结果添加到 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 中,这样您就可以避免花时间编译模板客户端。

【讨论】:

  • 所以,如果我的方法正确,请告诉我。您预编译了牛模板,这就是您单击链接后显示的内容。现在,目标是从另一个文件加载模板,您正在从 .compile(code) 加载代码。这样我应该使用一些 ajax 来获取该文件并检索数据,对吗?我错过了您对预编译的建议(不是总是预编译吗?)。抱歉,我正试图在这里了解全部情况。
  • 没问题,想问多少就问多少!查看更新的答案。
  • 令人惊叹,不仅有效,而且还清除了余烬模板的一些方面。再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-07
  • 2019-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多