ember.js: Cannot observe changes to nested properties on array using @each
Adding an observer on a nested property of objects within a collection does not reliably fire. I’ve created a test case that could be added to ember-runtime/tests/mixins/array_test.js that illustrates this. Observing a nested property on the EachProxy itself appears to work fine. However, observing the property using @each.nest.isDone does not.
In the following test, count1 is incremented to 1, count2 is not:
test('modifying nested contents of an object in an array should call @each observers', function() {
var ary = new TestArray([
Em.Object.create({ nest: Em.Object.create({ isDone: false}) }),
Em.Object.create({ nest: Em.Object.create({ isDone: false}) }),
Em.Object.create({ nest: Em.Object.create({ isDone: false}) }),
Em.Object.create({ nest: Em.Object.create({ isDone: false}) })
]);
var get = Ember.get, set = Ember.set;
var count1 = 0, count2 = 0;
// Works
var each = get(ary, '@each');
Ember.addObserver(each, 'nest.isDone', function() { count1++; });
// Doesn't work
Ember.addObserver(ary, '@each.nest.isDone', function() { count2++; });
count1 = count2 = 0;
var item = ary.objectAt(2);
get(item, 'nest').set('isDone', true);
equal(count1, 1, '@each.nest.isDone should have notified - observing @each array');
equal(count2, 1, '@each.nest.isDone should have notified - observing chain containing @each');
});
About this issue
- Original URL
- State: closed
- Created 12 years ago
- Comments: 75 (62 by maintainers)
Commits related to this issue
- Document that nested @each does not work — committed to emberjs/website by joliss 11 years ago
- WIP: try suggestion from GH comments https://github.com/emberjs/ember.js/issues/541#issuecomment-370193879 — committed to EmberMN/ember-cli-plotly by jacobq 6 years ago
- WIP: try suggestion from GH comments https://github.com/emberjs/ember.js/issues/541#issuecomment-370193879 — committed to awesome341/Ember.js-Plotly.js by awesome341 6 years ago
- Merge pull request #541 from ember-learn/dependabot/npm_and_yarn/acorn-5.7.4 [Security] Bump acorn from 5.7.3 to 5.7.4 — committed to sandstrom/ember.js by jaredgalanis 4 years ago
You can just add new computed property, which will contains only very nested object, which you’re trying to observe. And @each will works correctly Use next method
instead of
This is the Ember issue I encounter most frequently lately, often because it is hidden behind something else, like a filter or sort CP macro where it’s easy to forget you effectively creating a dependent key that is an @each with nested properties.
Historically (pre-2.0), capitalized paths indicated a global (so in your case it would be observing
window.A). This issue is talking about nested paths with @each, which your comment is not discussing.Most (hopefully all) of the special casing of capitalized paths should be removed. We should test against 2.8.1. If it still isnt working on 2.8, please open a new issue with a twiddle/jsbin reproduction.
@rwwagner90 regarding observers, my take on it is that using observers in cases when you’re not interacting with non-ember code is a big code smell. So using observers to e.g. trigger a d3 graph rendering when your app data changes is totally legit, but using observers to set one ember property when another changes is almost always more easily accomplished with a different approach
This is so easy to miss in the guides. I believe it should issue a warning when a nested @each is found.