Reputation: 1126
I know this is against the data down actions up idea but, following it my parent component is seeming to be very populated.
So, I am looking if there is another way.
Example case: I have a parent component holding "filters", "table" and "options". Now when a user select another table from options, the filter has to be reset. Thus, I need to trigger reset filter from parent component.
Upvotes: 1
Views: 1937
Reputation: 12872
You can bind parent-component property to child component, and you can react to parent component property change without an observer through components hook. This will adhere Data Down Actions Up(DDAU) principle and avoided observer.
In the below example,
whenever selectedOptionId
changed in parent-component, then in child component(my-table) will start rerendering by calling following hooks in the order (didUpdateAttrs
, didReceiveAttrs
, willUpdate
, willRender
, didUpdate
, didRender
). You will get newAttrs
and oldAttrs
property from options
argument from didUpdateAttrs and didReceiveAttrs hook.
For first time rendering there won't be options.oldAttrs
in didReceiveAttrs hook.
templates/application.hbs
{{parent-component }}
{{outlet}}
templates/components/parent-component.hbs
{{my-table selectedOptionId=selectedOptionId}}
<button {{action 'changeOption'}}> Change Option </button>
{{yield}}
**components/parent-component.js
import Ember from 'ember';
export default Ember.Component.extend({
selectedOptionId:1,
actions:{
changeOption(){
this.set('selectedOptionId',2);
}
}
});
templates/components/my-table.hbs
{{selectedOptionId}}
{{yield}}
components/my-table.js
import Ember from 'ember';
export default Ember.Component.extend({
didReceiveAttrs(options){
this._super(...arguments);
//this will run both initial render and rerender.
//For initial rendering alone options.oldAttrs will not be available
},
didUpdateAttrs(options){
this._super(...arguments);
//this will run only for the rerender
if(options.oldAttrs.selectedOptionId.value !== options.newAttrs.selectedOptionId.value) {
this.send('triggerOptionChangeEvent');
}
},
actions:{
triggerOptionChangeEvent(){
console.log('triggerOptionChangeEvent ',this.get('selectedOptionId'));
}
}
});
Update: From ember guides,
Note: Observers are often over-used by new Ember developers. Observers are used heavily within the Ember framework itself, but for most problems Ember app developers face, computed properties are the appropriate solution.
so always stay away from using observer. We should not even use options
in life cycle hook methods. that's deprecated. so we should manually find the particular property is changed or not. That's the correct way. Refer this RFC for more details. It contains correct approach to avoid using opions
property from didReceiveAttrs
.
Refer stefan penner excellant talk to solve the problem without using the observer.
Upvotes: 1