I’m using KnockoutJS and trying to subscribe to an observable that is in an observableArray that is in an observableArray. So my viewModel looks like this…
function viewModel() {
// private properties
var self = this;
// public properties
self.movies = ko.mapping.fromJS([]);
// subscriptions
self.movies.UserMovies.Rating.subscribe(function(newValue) {
console.log(newValue);
});
}
The movies observableArray would look like this once populated from the mapping plugin…
[{
Id: 1,
Title: 'Movie1',
Year: 2010,
UserMovies: [{ Id: 11, Rating: 3.5, IsWatched: true }]
},{
Id: 2,
Title: 'Movie2',
Year: 2010,
UserMovies: [{ Id: 4, Rating: 4, IsWatched: true }]
}]
I’m trying to set up a subscription to UserMovies.Rating but, from my above viewModel getting the error message
TypeError: self.movies.UserMovies is undefined
How would I got about setting up a subscription to UserMovies.Rating when it is populated from the mapping plugin?
Knockout does not provide the granularity for knowing which items changed in an array, just that something changed. You will need to loop trough the array each time an item is added or removed.
The
foreachbinding (viako.utils.compareArrays) actually calculates the minimum number of operations to transform one array into another one, so that DOM-elements does not need to be recreated.Using
ko.utils.compareArrays, I was able to create a method that subscribes to array changes at an item level. Leveraging this, I could write aselectmethod that manages the subscriptions.http://jsfiddle.net/MizardX/s9M4z/
With the new
selectmethod, you could do this pretty concisely:It handles additions, updates, and deletions as expected.