So yes I can subscribe to an observable array:
vm.myArray = ko.observableArray();
vm.myArray.subscribe(function(newVal){...});
The problem is the newVal
passed to the function is the entire array. Is there anyway I can get only the delta part? Say the added or removed element?
None that I know of. Wanna know what I do? I use a previous variable to hold the value, something called
selectedItem
So that way, when something happens to my observable array, I know which item was added.
This is really verbose, and assuming your array holds many kinds of data, you would need to have some sort of flags that helps you know what to do with your saved variables...
An important thing to notice is that you might know which item was added if you know whether
push
orunshift
was used. Just browse the last item of the array or the first one and voila.Since I couldn't find any info on this elsewhere, I'll add a reply for how to use this with TypeScript.
The key here was to use the KnockoutArrayChange interface as TEvent for subscribe. If you don't do that, it'll try to use the other (non-generic) subscribe and will complain about status, index, and value not existing.
In order to only detect
push()
andremove()
events, and not moving items, I put a wrapper around these observable array functions.The original push function is stored in a closure, then is overlayed with a wrapper that allows me do do anything I want with the pushed item before, or after, it is pushed onto the array.
Similar pattern for
remove()
.As of KnockoutJS 3.0, there's an arrayChange subscription option on ko.observableArray.
In the above callback, the changes argument will be an array of change objects like this:
For your specific problem, you want to be notified of new or removed items. To implement that using Knockout 3, it'd look like this:
I am using a similar but different approach, keep track whether an element has been instrumented in the element itself:
But it is really tedious and the pattern repeated across my code
Try
vm.myArray().arrayChanged.subscribe(function(eventArgs))
That has the added value when an item is added, and the removed value when an item is removed.