Reputation: 50732
In EmberJS, if I want to observe a property "selectedValue" which is inside a nested model, how can I do that ?
The below does not seem to be working;
modelChanged: function() {
}.observes('myModel.@[email protected]'),
Also the below does not work
modelChanged: function() {
}.observes('myModel'),
This is how myModel looks like
[
[{
"prop1": "abc_1",
"selectedValue": "abc_1"
}, {
"prop1": "xyz_1",
"selectedValue": "xyz_1"
}],
[{
"prop1": "abc_2",
"selectedValue": "abc_2"
}, {
"prop1": "xyz_2",
"selectedValue": "xyz_2"
}],
[{
"prop1": "abc_3",
"selectedValue": "abc_3"
}, {
"prop1": "xyz_1",
"selectedValue": "xyz_1"
}]
]
Update based on
Seems to be working...Just a couple of questions;
In above code, "observedObjects" just adds for the first outer array and tracks property within this arr[0]. I have multiple outer array elements
How can I modify the above to track for multiple properties ? i.e. In some cases, it would be "selectedValue" OR it can be "preSelectedValue" in other cases . What property it is would depend upon that object itself. But I need to track change of either selectedValue/preSelectedValue
Also in observerMethod, can I get a context and check what the new selectedValue/preSelectedValue is?
Upvotes: 1
Views: 890
Reputation: 525
What is the structure of your nested model? If myModel is an array of elements with selectedValue, you can use [email protected]
. If you need multiple levels of nesting, that's not supported out of the box.
From the documentation:
Note that @each only works one level deep. You cannot use nested forms like [email protected] or [email protected][email protected].
There are workarounds that depend on your model structure, and if you reply or update the question with your structure I'll update my answer to cover an appropriate solution.
Update: Depending on how myModel
is set/updated, you may need to adjust when observeMyModelChildren
is called and how it creates observers.
// observerMethod is called when myModel.@[email protected] changes
observerMethod: function () {
// handle change
},
// observedObjects tracks child observers so they can be removed
observedObjects: [],
// observeMyModelChildren listens for changes to myModel, removes
// old observers, and adds new ones
observeMyModelChildren: function () {
const key = '@each.selectedValue';
this.get('observedObjects').forEach((el) => {
el.removeObserver(key, this, this.observerMethod);
});
this.set('observedObjects', []);
let observedObjects = [];
this.get('myModel').forEach((el) => {
el.addObserver(key, this, this.observerMethod);
observedObjects.pushObject(el);
});
this.set('observedObjects', observedObjects);
}.observes('myModel'),
Update 2: If you want to support observing multiple properties (e.g. other models), you can do do that by modifying observeMyModelChildren
:
observePropertyChildren: function (obj, attr) {
console.log('setting up observers on', attr);
var key = 'observedObjects.' + attr;
var observedObjects = this.get(key) || [];
observedObjects.forEach((el) => {
el.removeObserver('@each.selectedValue', this, this.observerMethod);
});
this.get(attr).forEach((el) => {
el.addObserver('@each.selectedValue', this, this.observerMethod);
observedObjects.pushObject(el);
});
this.set(key, observedObjects);
}.observes('myModel', 'myOtherModel'),
Upvotes: 1