如何通过变量动态调用ember组件?

Str*_*per 16 javascript ember.js

假设我的控制器上有一组窗口小部件对象,每个窗口小部件对象都有成员变量,该变量被分配了一个组件类的名称.如何让我的模板调用该组件?

//widgets[0].widget.componentClass="blog-post"

{{#each widget in widgets}}
    {{widget.componentClass}}
{{/each}}
Run Code Online (Sandbox Code Playgroud)

显然,上面的示例只是吐出一系列小部件组件类的字符串版本.然而,这确实有效(只要你设置好一切):

//widgets[0].widgets.viewClass="blogPost"

{{#each widget in widgets}}
    {{view widget.viewClass}}
{{/each}
Run Code Online (Sandbox Code Playgroud)

这是我们之前的实施,但我们对此并不满意.我们目前正在使用带有把手助手的自定义{{renderWidget ...}}标签,如下所述:使用变量名调用句柄{{render}}.默认的渲染助手有一个类似的问题,它不会在变量名的内容上调用渲染.我愿意写一个自定义组件把手助手,但我甚至无法弄清楚从哪里开始.谢谢.

Str*_*per 12

我试过这个似乎工作,但它只是我的很多猜测:

Ember.Handlebars.registerHelper('renderComponent', function(componentPath, options) {
  var component = Ember.Handlebars.get(this, componentPath, options),
      helper = Ember.Handlebars.resolveHelper(options.data.view.container, component);

  helper.call(this, options);

});
Run Code Online (Sandbox Code Playgroud)

你以同样的方式使用它:

{{#each widget in widgets}}
  {{renderComponent widget.componentClass widget=widget}}
{{/each}}
Run Code Online (Sandbox Code Playgroud)


wby*_*ung 10

在Ember 1.11中,component助手允许您这样做:

{{#each widget in widgets}}
  {{component widget.componentClass}}
{{/each}}
Run Code Online (Sandbox Code Playgroud)

截至今天,2015年1月19日,1.11不是一个稳定的版本,但此功能是在金丝雀版本.


zai*_*ius 6

听起来我遇到了很多和你一样的问题.所有组件都注册为顶级助手,这意味着您可以执行与创建执行查找的手柄助手相关联的方法.像这样:

Ember.Handlebars.registerHelper('lookup', function(component, options) {
  component = Ember.Handlebars.get(this, component, options);
  Ember.Handlebars.helpers[component].call(this, options);
});
Run Code Online (Sandbox Code Playgroud)

然后在你的模板中:

{{#each widget in widgets}}
  {{lookup widget.componentClass}}
{{/each}}
Run Code Online (Sandbox Code Playgroud)

这是一个带有工作示例的jsbin:http://jsbin.com/ucanam/2482/edit

希望有所帮助!

- 编辑 -

出于某种原因,新版本的把手使得从其他助手调用助手变得不可能.相反,您可以通过Ember.TEMPLATES全局查找模板.我已经更新了JSBin以使用此方法.

您也可以通过options.data.view.templateForName(component)它获取模板,但感觉比它更脆弱Ember.TEMPLATES.

- 编辑2 -

它再次改变了.Ember.Handlebars.resolveHelper现在是正确的方法.请参阅@ StrangeLooper的答案.