I'm trying to use DS.hasMany.addArrayObserver to monitor when new elements are inserted (either created client side or loaded from the server). However, the arguments passed to arrayWillChange and arrayDidChange are weird, in that if I add one record the removeCount is equal to the old HasMany length and the addCount is equal to the new HasMany length.
In other words, it looks like the "array" is emptied and all new records are added. Is this the expected behavior? If so, what is the proper way to get just the records which are being added/removed?
I have set up an example which demonstrates the difference in behavior between an array and a HasMany relationship: http://emberjs.jsbin.com/hozononusu/1/edit?html,js,console,output
Further research seems to yield that it is indeed (currently) the expected behavior, as flushCanonical creates a new array by filtering out deleted elements and appending new elements: https://github.com/emberjs/data/blob/339b79aa3ea82e9be1a8f39db36ec1133d0b65a2/packages/ember-data/lib/system/many-array.js#L67
So I have two questions:
flushCanonical talks about the need for "proper diffing". Has work on this started anywhere? (and how could I help with the need?)At least as a work around, I was able to using DS.Store.filter() to get the relevant records and call .addArrayObserver on those. More info on my StackOverflow question: http://stackoverflow.com/a/29561953/3108853
I also ran into this problem. My hasMany relationship looked like it was being "reset", by some reason.
I solved it by using an intermediate computed property to create a new array containing my elements.
componentMaterials: Ember.computed('model.someHasManyRelationship.[]', function() {
return DS.PromiseArray.create({
promise: this.get('model.someHasManyRelationship').then(r => {
return Ember.A().addObjects(r);
})
});
}),
I'm currently running into the same issue. I do have a big process each time a record is added / deleted to a relationship. With the current behavior, whenever i add something, everything is removed then everything is append again.
@miguelcobain With your solution, i don't even get the notification from the array observer. Did you find something else ?
PR #4583 should fix this
it looks like the "array" is emptied and all new records are added
Short answer, yes, this is exactly what is happening. Long answer, it's actually much worse than that but I'm working on refactoring and optimizing that layer. The work from @BryanCrotaz will likely help, but after looking at his approach and the different layers of the onion I suspect a more general array diffing algorithm is what we need but to use one we need to first correct the change flow / triplicated diff that's there right now.
@runspired I've refactored out a general array diff in PR #4583
https://github.com/emberjs/data/pull/4850 was merged, this can be closed.
Most helpful comment
@runspired I've refactored out a general array diff in PR #4583