How to get afterAdd to fire only for new items when replacing all the elements in an ObservableArray

34 views
Skip to first unread message

Kristian Kime

unread,
Aug 16, 2017, 10:20:53 AM8/16/17
to KnockoutJS
Hi all,

I've searched around but didn't seem to find a clear answer for this. So apologies if it's already been answered.

I have a view model with an observable array. I'm "bulk" updating it by replacing all the elements with a "ko.mapping.fromJS" call. However most of the elements are identical. Currently the function I register with afterAdd is called for all the elements (even the identical ones). Is there some way to have it get called only for the ones that differ? The list will not get that big so I'm not worried about computational time.

Here is jsfiddle with an example of what I'm talking about: https://jsfiddle.net/q63h8j28/2/.

Thanks in advance,
-Kristian

Michael Best

unread,
Aug 18, 2017, 4:41:47 PM8/18/17
to KnockoutJS
Knockout doesn't compare the signature of object, only their reference. In JavaScript {x: 1} !== {x: 1}.  I'm not familiar enough with ko.mapping, but you should be able to tell it to preserve existing objects. There's a whole section in http://knockoutjs.com/documentation/plugins-mapping.html about this.

Kristian Kime

unread,
Aug 21, 2017, 11:11:09 AM8/21/17
to KnockoutJS
Hi Thanks for getting back to me.

It looks like adding a Key (see the "Uniquely identifying objects using “keys"" section of http://knockoutjs.com/documentation/plugins-mapping.html) did indeed solve this.


I guess I was just confused a little bit by the language on the page. It says:
    "This happens because, by default, the mapping plugin simply compares the two objects in the array. And since in JavaScript the object { id : 1, name : 'Alicw' } does not equal { id : 1, name : 'Alice' } it thinks that the entire child needs to be removed and replaced by a new one."

I though the only reason it would say something like that was if  knockout would normally recursively compare values or something. But I guess I was reading too much into it :).
Reply all
Reply to author
Forward
0 new messages