JavaScript objects behave like dictionaries (more exactly associative arrays) regarding how you can access their properties. For example doing this:
var items = {};
items.Books = { "Type":2, "Count":20547 };
items.Games = { "Type":1, "Count":2647 };
is completely equivalent to this:
var items = {};
items["Books"] = { "Type":2, "Count":20547 };
items["Games"] = { "Type":1, "Count":2647 };
Of course, you can also use this syntax to read the values:
var books = items["Books"];
As long as using it in ko, you cannot use observableArray
, because it requires a JavaScript array, whose members are accessed by index. I.e. the items
object in the previous example is an object with properties, and not a JavaScript array.
So, in ko you need to use an observables, like this:
var obs = ko.observable(items);
But this observable will only notify changes when the whole items
object is changed, not when any of its properties, like Books
, is modified. If you need to get notifications (for example to udpta the view) when some of these properties changes, then you need to make observable the properties themselves, not onbly the root object items
. To do so, you can use ko.mapping plugin, or manually do it. This would be equivalent to do:
var items = ko.observale({
Books: ko.observable({
Type: ko.observable(2),
Count: ko.observable(20547)
}),
Games: ko.observable({
Type: ko.observable(1),
Count: ko.observable(2647)
})
});
In this case, whenever any of the properties changes, this will be notified.
However, if yu needed to notify when you added or remvoed a property like Books
, or Games
, there would be not direct way to work like that in ko. You'd need to map your object to a regular observable array, and make a ko.observableArray
to ge it working. The mapping could be like this:
var items = [
{ Name: 'Books', Type: 2, Count: 20547 },
{ Name: 'Games', Type: 1, Count: 2647 }
];
If you do so, you can create an observable array. If you still need to access the properties by Name
, you can use JavaScript methods (depending on the version of EcmaScript supported by your browser) or use a library like lodash or underscore, which offers powerful ways to access, and map JavaScript objects and collections.
NOTE: ko expressions are able to detect that something is an observable, and unwrap its value. However, if you need to access an observabe property of an observable object, you have to use parentheses in the all levels, but the final, for example data-bind="value: items().Books().Type", in the case you used ko mapping or mapped it as explained in the code block before the last one. If you need more info, please, read this: When to use or not use parentheses with observables in data-binding expressions.