将ember.js .hbs模板渲染为字符串

时间:2015-01-14 18:56:02

标签: ember.js handlebars.js

我目前可以执行以下操作:

var template = Handlebars.compile("Hello <em>{{name}}</em>!");
var html = template({ name: 'World' });

html变量现在包含字符串"Hello <em>World</em>!"

但是如何使用代码位于.hbs目录中的app/templates文件中的模板呢?

(我正在使用ember-cli和ember 1.9.1)

1 个答案:

答案 0 :(得分:4)

在Ember 1.13.15 中,这将有效( UPDATE 与底部的v2.4一起使用):

// template-to-string.js
import Ember from 'ember';

export default function(container, template, context) {
  let resolvedTemplate =
    typeof template === 'string' ? container.lookup('template:' + template) : template;
  context = context || {};

  Ember.assert(`Template '${template}' could not be resolved`, !!template);

  return new Ember.RSVP.Promise((resolve) => {

    Ember.Component.create(Ember.merge({
      style: 'display:none;',
      layout: resolvedTemplate,
      container,

      didRender() {
        resolve(this.$().html());
        this.destroy();
      }
    }, context)).append();

  });
}

它基于此帖中提出的解决方案:How to Render an HTMLBars Template to a String in Ember 2.0?,其中提供了进一步的解释。

我已经扩展到支持传递模板上下文。

使用如下功能:

// my-component.js
import Ember from 'ember';
import templateToString from './template-to-string';

export default Ember.Component.extend({

  _appendMyChildTemplate() {
    let myTemplateContext = ...;

    templateToString(this.container, '<my-template-path>', myTemplateContext)
     .then((html) => {
       this.$().append(html);
     });
  }

})

更新在Ember 2.4中工作:

我无法声称完全理解这一点,或者它是最接近最佳解决方案的地方,但它确实有效:)

与上述功能没有太大差别:

import Ember from 'ember';

export default function(container, template, context) {
  let resolvedTemplate =
    typeof template === 'string' ? container.lookup('template:' + template) : template;
  context = context || {};

  Ember.assert(`Template '${template}' could not be resolved`, !!template);

  return new Ember.RSVP.Promise((resolve) => {

    Ember.Component.extend(Ember.merge({
      style: 'display:none;',
      layout: resolvedTemplate,
      container,

      init() {
        this._super.apply(this, arguments);
        Ember.setOwner(this, container);
      },

      didRender() {
        resolve(this.$().html());
        this.destroy();
      }
    }, context))
      .create()
      .append();

  });
}