The EmberMap screencast on DDAU input events was a huge moment for me.
However, I’m curious why
this.notifyPropertyChange('key.path') doesn’t seem to work. It has to be
this.get('key').notifyPropertyChange('path') (which means that
key must be an Ember.Object).
Here’s a twiddle reproducing the issue.
Should this work? If not, why not?
The episode was fantastic. They explained DDAU in a way that no blog post ever did.
notifyPropertyChange is actually a low level API on ember object. It isn’t a high level API like you would expect in say a computed property. Notification of change are core to KVO (Key-Value Observing) in Ember. Since the API is designed on a per object level there is no point in having dot-notation nesting.
To perform as you suggest your actually working on the wrong abstraction layer. You saying that your top level component knows more about your
key does. The correct level for notifications would be the object that owns the properties not some consumer of that object.
At the abstraction level your at in the example provided your component is only responsible for it’s own properties; meaning to accomplish a KVO notification it would have to be
this.notifyPropertyChange('key') since key is under its ownership.
path however is the responsibility of the
key object. It should know when and how to notify any KVO.
All these dependencies and nesting comes to a hierarchy where at the bottom is an observer and the top a scalar value. In the case of Ember the observer is in the Glimmer engine and should always be the very last thing in the chain (hence why using observers yourself in components is highly frowned upon). This observer will perform a
this.get() which asks did my dependencies change? if so recalculate. Otherwise, return the save value as before. Each step in that hierarchy will in turn perform
this.get() which asks did my dependencies change? This continues till all computed properties are resolved.
In the normal case of Ember development the difference between a changed dependency and a cached one is simply the use of
this.set() which will internally call
In your example above there are two conclusions to draw from:
- Don’t worry about the lower level nesting. A
this.notifyPropertyChange('key') is enough to mark
key.path as dirty and trigger Glimmer to start the
- If you wish to be more explicit you can make a component level property that aliases to the nested one:
keyPath: reads('key.path') then