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

Render ember.js .hbs template to a string

我目前可以做到以下几点:

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

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

但是我怎样才能对代码在我的 app/templates 目录中的 .hbs 文件中的模板执行相同的操作?

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

在 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();

  });
}

它基于此 post 中提出的解决方案: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();

  });
}