Is there a better (built in?) way to mix observableArray and associative arrays?
viewModel = {
a: ko.observableArray(),
a_assoc: {},
add_item: function(i) {
if (typeof this.a_assoc[i] == 'undefined') {
this.a.push(i);
this.a_assoc[i]=1;
}
}
}
viewModel.add_item('bla');
I think it is best to use an associative array under the hood for performance. You also (as you alluded to) need to use an observableArray to be able to track changes (because that's how knockout works).
If you're seeking a 'knockout friendly' associative array you probably want a way to track changes to the item (and thus affect dependency chains).
http://jsfiddle.net/rz41afLq/2/
Here's what I came up with that suited my needs. Basically you store a key value pair in the
observableArray
and use a standard associative array to store a copy for lookup purposes.So you save your dogs like this:
(The second is only required if you are planning on calling
pop()
orpush()
on the list of dogs and want to update the UI. You can of course callupdate_item
to completely update the item at any time in which case it doesn't need to be observable)To lookup a value, you dynamically create a computed to go fetch it :
Then as soon as the value indexed as 'dogs' in the associative array changes then the observable
dogs()
will update (and can be chained). Thisdogs
observable can be bound to the UI of courseTypically, you would do something like this in Knockout:
So, you have a dependentObservable that maps your array to an object. Note that each time that the original array is updated, the object is rebuilt. So, it is less efficient than the method in your post, but unless your object is substantially big, it is doubtful that it would cause a performance issue.
Sample here: http://jsfiddle.net/rniemeyer/PgceN/