I have model
import DS from 'ember-data';
export default DS.Model.extend({
Structure: DS.attr('raw'),
});
So, structure is array of objects
[{
type: 'comp-a',
children: [
{type: 'comp-b'},
{type: 'comp-b'}
]
}]
Next, i print this structure
structure: Ember.computed('model.Structure', function() {
var st = this.get('model.Structure');
// handle this structure
return st;
});
{{#each structure as |item|}}
{{component item.type}}
{{/each}}
Question.
When I push object to comp-a
, Ember renders new pushed component
this.get('model.Structure')[0].children.pushObject({
type: 'comp-b'
});
But, when I remove any object it doesn’t.
var child = this.get('model.Structure')[0].children[0];
this.get('model.Structure')[0].children.removeObject(child);
You need to add the children array to your computed properties list of dependent keys.
From:
To:
structure: Ember.computed('model.Structure', 'model.Structure.children.[]', function() {
var st = this.get('model.Structure');
// handle this structure
return st;
});
Ok thanks. But Structure is dynamic and I don’t know the depth of children beforehand.
Because you’re needing to observe at an arbitrary depth — you’ll either want to have a component for each of those levels that can set up the computed property for each of the child arrays, or perhaps use a helper of some sort inside your {{#each}}
helper.
For example, if you take this helper (a bit inspired by ember-composable-helpers
) – it is going to set up an observer on the array and watch for any push/removes performed on the array and return a new array instance every time something changes.
// helpers/observe-array.js
import Ember from 'ember';
export default Ember.Helper.extend({
compute([array]) {
this.set('array', array);
return Ember.A(array.slice(0));
},
arrayContentDidChange: Ember.observer('array.[]', function() {
this.recompute();
})
});
Then, your template would get updated like so:
{{#each (observe-array structure) as |item|}}
{{component item.type}}
{{/each}}
…then…that should “just work” given how it seems you’re handling everything else right now.