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

时间:2013-09-24 02:51:13

标签: javascript ember.js

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

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

{{#each widget in widgets}}
    {{widget.componentClass}}
{{/each}}

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

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

{{#each widget in widgets}}
    {{view widget.viewClass}}
{{/each}

这是我们之前的实施,但我们对此并不满意。我们目前正在使用自定义{{renderWidget ...}}标记,其中包含如此处所述的把手助手:Calling Handlebars {{render}} with a variable name。默认的渲染助手有一个类似的问题,它不会在变量名的内容上调用渲染。我愿意写一个自定义组件把手助手,但我甚至无法弄清楚从哪里开始。感谢。

4 个答案:

答案 0 :(得分: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);

});

你以同样的方式使用它:

{{#each widget in widgets}}
  {{renderComponent widget.componentClass widget=widget}}
{{/each}}

答案 1 :(得分:10)

在Ember 1.11中,new component helper允许您这样做:

{{#each widget in widgets}}
  {{component widget.componentClass}}
{{/each}}

截至今天,2015年1月19日,1.11不是稳定版本,但此功能在the canary version

答案 2 :(得分:6)

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

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

然后在你的模板中:

{{#each widget in widgets}}
  {{lookup widget.componentClass}}
{{/each}}

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

希望有所帮助!

- 编辑 -

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

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

- 编辑2 -

又改变了。 Ember.Handlebars.resolveHelper现在是正确的方法。请参阅@ StrangeLooper的回答。

答案 3 :(得分:2)

如果你使用Ember CLI和Coffeescript,那么这是一个版本。在app/helpers/render-component.coffee中创建以下文件:

renderComponent = (componentPath, options)->
  helper = Ember.Handlebars.resolveHelper(options.data.view.container, componentPath)
  helper.call this, options

`export { renderComponent }`
`export default Ember.Handlebars.makeBoundHelper(renderComponent)`

从那里,您可以从模板中调用{{render-component "foo-bar"}}

由于Ember生态系统不断变化,以下是我测试它的版本:

  • Ember-CLI v0.0.43
  • Ember v1.7.0
  • Handlebars 1.3.0