我在组件中有一个组件。子组件有两个通过模板传入的属性。这些属性在子组件的组件中都有单独的观察者。
当我按特定顺序更新父组件中的绑定属性时,子组件的观察者以错误的顺序触发。
如何控制观察者在子组件中触发的顺序?
我的具体案例。
有人向我指出,观察员不再是必要的了。但它们仍然存在于ember 2.0中,因此必须使用它们。无论如何我会解释我的情况,希望你们的聪明才能让我知道如何在没有观察员的情况下实现这一目标。
在我的情况下,父组件是游戏的菜单,包含许多子菜单。要在每个子菜单之间切换,我使用幻灯片动画,以便当前菜单从屏幕上消失,新菜单进入并根据需要交换两个动画菜单。这是在侧面切换器组件(本例中为子)中完成的。
父级菜单包含的标签在点击时需要与子侧切换器组件进行通信,现在应该显示哪个子菜单,以及要滑动的方向(两个属性)。首先需要设置方向,然后是子菜单,因为当子菜单发生变化时,触发实际动画的是子菜单。 Ember 2.0哲学规定行动不能下降,但数据(属性)可以,因此观察属性是我正在走的道路。
注意,在我的用例中,它实际上只是被观察到的菜单属性,但在调试时,我不得不观察方向属性,因为我的菜单在整个地方滑动错误。
答案 0 :(得分:0)
首先需要设置方向,然后是子菜单,因为子菜单发生变化时,触发实际动画的是什么。 Ember 2.0哲学指出行动不能下降,但数据(属性)可以,因此观察属性是我走下坡路。
我认为您可以使用didInitAttrs
和didReceiveAttrs
挂钩来摆脱观察者。这些钩子有助于将属性一起处理,而无需考虑顺序。详情:http://emberjs.com/blog/2015/06/12/ember-1-13-0-released.html#toc_component-lifecycle-hooks
让子组件具有属性direction
和submenu
。
//parent component template
{{child-component direction=direction submenu=submenu}}
您可以按getAttr
获取属性并根据需要进行处理:
// child component
direction: defaultValue,
submenu: defaultValue,
didReceiveAttrs() {
// your logic
this.set('direction', this.getAttr('direction') || defaultDir);
this.set('submenu', this.getAttr('submenu') || defaultSumbenu);
}
警告:现在,ember指南和文档缺少对生命周期挂钩的解释。可以建议将ember-collection addon code视为工作示例。
答案 1 :(得分:0)
感谢Artych,它实际上是didUpdateAttrs
钩子解决了我的问题,因为我需要能够对其中一个属性的所有更改作出反应,与初始化分开。
鉴于如此消耗的组件:
{{my-component myAttr=changeableAttr myOtherAttr=otherAttr}}
在component.js中:
didUpdateAttrs(options){
if( options.newAttrs.myAttr !== options.oldAttrs.myAttr ){
// React to changes outside the component
}
},
在任何给定的运行循环中所有属性更改后触发,并允许您以任何顺序在组件内进行处理。
这也回答了如何为我发送组件动作的问题,或者更准确的问题,如何让组件对外部变化做出反应。
为了完整起见,我确实研究了如何改变观察者被触发的顺序:它只是在模板中的组件上定义它们的顺序。这是非常糟糕的设计依赖于此,因此有一个更好的解决方案,以didUpdateAttrs
或didReceiveAttrs
的形式。