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

Posted

技术标签:

【中文标题】如何通过变量动态调用 ember 组件?【英文标题】:how can I invoke an ember component dynamically via a variable? 【发布时间】:2013-09-29 02:43:58 【问题描述】:

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

//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。默认的渲染助手有一个类似的问题,它不会对变量名的内容调用渲染。我愿意编写一个自定义组件车把助手,但我什至不知道从哪里开始。谢谢。

【问题讨论】:

【参考方案1】:

听起来我遇到了很多和你一样的问题。所有组件都注册为***助手,这意味着您可以执行与您链接的方法类似的方法,即创建执行查找的把手助手。像这样:

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 的回答。

【讨论】:

这似乎不适用于最新的 ember。有什么建议?谢谢。 刚刚尝试实现这个助手,它似乎没有调用组件的js部分,只是模板部分。【参考方案2】:

我试过了,它似乎有效,但这只是我的很多猜测:

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

【讨论】:

使用此模式我将如何修改对已解析组件的调用以传递一些任意参数值(例如,如果它是表单输入组件,则设置 value 参数),如以及设置应该在组件的yield中插入的内容? @StrangeLooper 这在 Ember 1.10 中不起作用,错误表明您应该使用 Component 或 makeBoundHelper 代替。将其更改为绑定助手后,我收到一条错误消息,提示找不到 renderComponent 助手。任何线索?也许是 Ember 1.10 的重构版本?谢谢【参考方案3】:

如果您使用的是 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 车把 1.3.0

【讨论】:

【参考方案4】:

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

#each widget in widgets
  component widget.componentClass
/each

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

【讨论】:

很不错的功能,就是不知道怎么传额外的参数。 component widget.componentClass var1=item var2=this 应该可以吗?

以上是关于如何通过变量动态调用 ember 组件?的主要内容,如果未能解决你的问题,请参考以下文章

从 Ember 中的控制器操作返回一个承诺?

如何在 Ember CLI 应用程序中访问 Ember 全局“App”变量?

C#中如何调用动态链接库DLL

如何基于先前的服务器端调用创建动态 Angular JS 4 子组件

在 PowerShell 中调用动态变量

vuejs中通过变量动态调用方法