【问题标题】:EmberJS trigger action on parent component from childEmberJS 从子组件触发对父组件的操作
【发布时间】:2014-11-22 05:38:10
【问题描述】:

我正在尝试创建一个下拉菜单组件。它包含 2 个组件 - currency-dropdown (parent)dropdown-item (child)。我能够渲染组件。但是当我点击dropdown-item 组件时,我无法触发父组件上的操作。

我正在尝试将选定的组件数据发送到父组件。我尝试设置 targetObject 和我在这里找到的许多其他组合。我不确定问题是什么。我确实在父组件中扩展了_yield,因为我在每个助手中渲染子组件。一些帮助将不胜感激。 Here is what I've got so far.

App.CurrencyDropdownComponent = Ember.Component.extend({
    actions: {
        itemSelected: function(item) {
            console.log(item);
        }
    },
    _yield: function(content, options) {
        var get = Ember.get,
        view = options.data.view,
        parentView = this._parentView,
        template = get(this, 'template');
        if (template) {
            view.appendChild(Ember.View, {
                isVirtual: true,
                tagName: '',
                _contextView: parentView,
                template: template,
                context: get(view, 'content'),
                controller: get(parentView, 'controller'),
                templateData: { keywords: parentView.cloneKeywords() }
            });
        }
    }
});

App.DropdownItemComponent = Ember.Component.extend({
    click: function() {
        this.sendAction('selectItem', this.origContext);
    }
});

<script type="text/x-handlebars" id="index">
  <header>
    {{#currency-dropdown currencies=model}}
      {{#dropdown-item targetObject=view selectItem="itemSelected"}}
        <span class="cdd-selected-tick">&#10004;</span>
        <span class="font-13">{{name}}</span>
        <span class="push-right font-11">{{symbol}}</span>
      {{/dropdown-item}}
    {{/currency-dropdown}}
  </header>
</script>

<script type="text/x-handlebars" id="components/currency-dropdown">
  <div class="cdd-box">
    <input class="cdd-input" type="hidden"/>
    <div class="cdd-selected-box" {{action "toggleDropDown"}}>
      <strong>Currency</strong>
      <span class="uppercase"> {{currencies.0.currencyCode}} </span> 
      {{currencies.0.symbol}}
      <div class="down-arrow"></div>
    </div>
    <ul class="cdd-selection-box" >
      {{#each item in currencies}}
         <li>{{yield}}</li>
      {{/each}}
    </ul>
  </div>
</script>

For anyone interested I have made my solution an addon.

【问题讨论】:

标签: javascript ember.js


【解决方案1】:

所以我找到了一种方法来做到这一点,但我认为这可能有点小技巧。您的问题是,就上下文而言,您的下拉项目不应访问您的货币下拉列表。通过使用yield,您为下拉项目提供了与货币下拉菜单相同的上下文,而不是货币下拉菜单本身的上下文。这是一个奇怪的场景,因为你想要两全其美,但你只能拥有一个或另一个。因此,您可以执行以下操作,而不是发送操作:

this.get('parentView').send('itemSelected', this.origContext);

这将调用您想要的操作处理程序。只有两个警告:

  1. 它将这些组件耦合在一起,使得dropdown-item 组件可能无法重用。
  2. dropdown-item 组件总是会调用该操作,而不仅仅是在父组件订阅它时。

另外,我不了解您的整个用例,但我认为您可能正在尝试使此组件可重用。我个人根本不会使用yield,而是将下拉项目的HTML 硬编码到下拉组件类中。硬编码某些特定于您的应用程序的内容会使其在您的应用程序之外的可重用性降低,但可以更轻松地在您的应用程序内部使用(这显然更重要)。在使用解决方法之前,您可能需要再看一下如何使用这些组件。从长远来看,像这样的解决方法总是会反过来咬我。

【讨论】:

  • 谢谢这确实有效。我基本上是在尝试创建一个下拉组件,我们可以在其中为选择项指定一个模板,如果可能的话,为一旦选择一个项目指定一个模板。你可能是对的太可重用了。我只是弄清楚组件及其用法。产量有点使这件事复杂化。
猜你喜欢
  • 2019-02-15
  • 1970-01-01
  • 2015-08-08
  • 2017-06-23
  • 1970-01-01
  • 1970-01-01
  • 2019-10-20
  • 2018-10-27
  • 2017-03-03
相关资源
最近更新 更多