I know DDAU, I know Components should not mutate data it receives, but what if data comes from Component itself? How should I properly set them and pass them to other components? (maybe to nested children or irrelevant components)
For demonstration, let’s see some code:
export default Ember.Component.extend({
didRender() {
// 1. didRender is required, because I need the DOM existed
// 2. didInsertElement could be used instead, but we often need to do
// things after each rendering, UI is changing constantly.
let clientRect = this.element.getBoundingClientRect();
// Now we can get width/height/top/right/bottom/left, these are the
// data we really want
// If children components need these data (depends on parent's DOM position)
// we want to pass them down, so we set them as property(ies)
this.set('positions', clientRect)
}
})
This demo shows what I need to say very straight forward, but it did in a wrong way.
First, Ember will warning like this:
A property of <YourApp@view:-outlet::emberXXX> was modified inside the didUpdate hook.
You should never change properties on components, services or models during didUpdate
because it causes significant performance degradation.
[deprecation id: ember-views.dispatching-modify-property]
It is reasonable (even it tells you didUpdate
instead of didRender
), I’ve already been suffered with this.
But even I can understand that, I still don’t know how to improve that. It is required to use didRender
because the DOM has to be ready; it is required to set/mutate data as properties because other components need them, DDAU can’t work here because the data we need is actually comes from the component itself.
Someone suggested to use CP, I don’t understand what is the difference here, maybe I’m stupid but what I can imagine is something like this:
export default Ember.Component.extend({
// Ok, we define a CP, but what things to look over?
positions: Ember.computed(/* what? */, {
get() {
return /* what? */
}
}),
didRender() {
// Still need to do here, right?
let clientRect = this.element.getBoundingClientRect();
// then, how to tell `positions` to compute itself?
}
})
What’s your suggestion? please enlighten me, I can’t solve this problem for days, really makes me crazy now.