If you want to detect and respond to changes on one object, you’d use observables. If you want to detect and respond to changes of a collection of things, use an observableArray. This is useful in many scenarios where you’re displaying or editing multiple values and need repeated sections of UI to appear and disappear as items are added and removed.
var myObservableArray = ko.observableArray(); // Initially an empty array myObservableArray.push('Some value'); // Adds the value and notifies observers
To see how you can bind the observableArray to a UI and let the user modify it, see the simple list example.
Simply putting an object into an observableArray doesn’t make all of that object’s properties themselves observable. Of course, you can make those properties observable if you wish, but that’s an independent choice. An observableArray just tracks which objects it holds, and notifies listeners when objects are added or removed.
If you want your observable array not to start empty, but to contain some initial items, pass those items as an array to the constructor. For example,
// This observable array initially contains three objects var anotherObservableArray = ko.observableArray([ { name: "Bungle", type: "Bear" }, { name: "George", type: "Hippo" }, { name: "Zippy", type: "Unknown" } ]);
Behind the scenes, an observableArray is actually an observable whose value is an array (plus, observableArray adds some additional features described below). So, you can get the underlying JavaScript array by invoking the observableArray as a function with no parameters, just like any other observable. Then you can read information from that underlying array. For example,
alert('The length of the array is ' + myObservableArray().length); alert('The first element is ' + myObservableArray()[0]);
Technically you can use any of the native JavaScript array functions to operate on that underlying array, but normally there’s a better alternative. KO’s observableArray has equivalent functions of its own, and they’re more useful because:
The rest of this page describes observableArray’s functions for reading and writing array information.
The indexOf function returns the index of the first array item that equals your parameter. For example, myObservableArray.indexOf('Blah') will return the zero-based index of the first array entry that equals Blah, or the value -1 if no matching value was found.
The slice function is the observableArray equivalent of the native JavaScript slice function (i.e., it returns the entries of your array from a given start index up to a given end index). Calling myObservableArray.slice(...) is equivalent to calling the same method on the underlying array (i.e., myObservableArray().slice(...)).
observableArray exposes a familiar set of functions for modifying the contents of the array and notifying listeners.
All of these functions are equivalent to running the native JavaScript array functions on the underlying array, and then notifying listeners about the change:
For more details about these observableArray functions, see the equivalent documentation of the standard JavaScript array functions.
observableArray adds some more useful methods that aren’t found on JavaScript arrays by default:
The destroy and destroyAll functions are mainly intended as a convenience for developers using Ruby on Rails:
So, what’s this _destroy thing all about? It’s only really interesting to Rails developers. The convention in Rails is that, when you pass into an action a JSON object graph, the framework can automatically convert it to an ActiveRecord object graph and then save it to your database. It knows which of the objects are already in your database, and issues the correct INSERT or UPDATE statements. To tell the framework to DELETE a record, you just mark it with _destroy set to true.
Note that when KO renders a foreach binding, it automatically hides any objects marked with _destroy equal to true. So, you can have some kind of “delete” button that invokes the destroy(someItem) method on the array, and this will immediately cause the specified item to vanish from the visible UI. Later, when you submit the JSON object graph to Rails, that item will also be deleted from the database (while the other array items will be inserted or updated as usual).
Normally, an observableArray notifies its subscribers immediately, as soon as it’s changed. But if an observableArray is changed repeatedly or triggers expensive updates, you may get better performance by limiting or delaying change notifications. This is accomplished using the rateLimit extender like this:
// Ensure it notifies about changes no more than once per 50-millisecond period myViewModel.myObservableArray.extend({ rateLimit: 50 });
© Steven Sanderson, the Knockout.js team, and other contributors
Licensed under the MIT License.
http://knockoutjs.com/documentation/observableArrays.html