如何在ember JS中调用子组件对父事件的操作

时间:2018-04-30 06:49:30

标签: ember.js

我知道我们可以从子组件中调用父组件的动作,但我想要的是它的反向。
我有一个父组件,在其中我有一个子组件,所以我试图在父组件事件上触发子组件的操作。 我试过sendAction,但没有运气。

4 个答案:

答案 0 :(得分:0)

你不能。行动只能向上泡,而不是向下泡。来自docs

  

如果模板的上下文是控制器,则当控制器未实现指定的操作时,以这种方式使用的操作将冒泡到路由。一旦某个动作遇到某个路线,它就会通过路线层次结构 [up]

虽然这个文档确实谈到了正常的' route-controller-actions,同样适用于组件动作。我认为您需要重新构建代码,因为永远不需要将操作调用到子路由/组件。

答案 1 :(得分:0)

这个答案至少适用于1.13,并且是从3.x开始编写的。

您无法从父路线触发对子组件的操作。但是,您可以创建一个可以由路由和组件,跨路由以及兄弟组件之间注入和使用的服务。

Service docs in The Guides

当您以这种方式共享状态/功能时要小心谨慎,并问自己是否有更简单,更直接的方法来处理事件。我谨慎使用服务。

答案 2 :(得分:0)

首先让我说 NO WAY 我是否推广这样做,因为有更好的解决方案。

尽管它违反了Ember的DDAU,但仍有可能。基本上,您需要将您的子组件注册到您的父组件,以便您可以访问他们的方法和操作。我已经看到了一些非常复杂的情况,需要类似下面的方法。我只推荐这作为最后的手段。

子组件didInsertElement hook:

...
didInsertElement(){
    this.get('parentView').register(this);
} 

父组件代码:

...
child: null,
register(child){
    //you would push the children to some array here
    //or if you only have one child you could just set a property
    this.set('child', child);
}

这允许您的父组件可以直接访问子项,这允许您将操作发送给它们。如下。

...
this.get('child').send('some-action');

注意:我自己没有测试过此代码,因此可能需要进行一些调整。

修改

当Ember弃用“childViews”时,我主要从后面获得了这个。这是针对依赖它的应用程序的建议解决方案。这个github对话详细阐述了这个问题。 https://github.com/emberjs/ember.js/issues/11244

答案 3 :(得分:0)

根据情况,可能可行的是在组件中设置一个计算属性以监视外部更改的数据。换句话说,可以按照数据减少/动作增加约定触发组件外部发生的数据更改来做某事。

示例:

// parent.hbs
{{my-component watchedValue=someDynamicValue}}

// my-component.js
computedValue: computed('watchedValue', function() {
    let watchedValue = get(this, 'watchedValue');

    // optionally do something...

    // ...and/or optionally send an action internally
    this.send('updateStuff', watchedValue);

    //return something (arbitrary value in this example)
    return watchedValue;
}),

actions: {
    updateStuff(value) {
        // do something
    }
}

// my-component.hbs
<p>The value is currently {{computedValue}}</p>

请注意computed properties will only recompute when they are consumed,因此尽管模板中不必使用computedValue,但可以在模板中使用get()。另请注意,此特定内容可能会引入side effects