【问题标题】:how can I invoke an ember component dynamically via a variable?如何通过变量动态调用 ember 组件?
【发布时间】:2023-03-24 10:27:01
【问题描述】:

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

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

【问题讨论】:

    标签: javascript ember.js


    【解决方案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}} 应该可以吗?
      猜你喜欢
      • 2014-08-30
      • 2014-01-04
      • 2020-11-03
      • 2018-06-25
      • 2015-05-18
      • 1970-01-01
      • 2019-04-09
      • 1970-01-01
      相关资源
      最近更新 更多