I’m pretty new to Knockout.js and am facing now a situation where I’m not really sure how to handle it right. The thing is: I got a bunch of objects that I’m retrieving via ajax. The result will be somewhat like this:
var Objects = [ { id: 0, name: "Foo", type: "A" },
{ id: 1, name: "Bar", type: "B" },
{ id: 1, name: "Bar", type: "A" }, ... ];
What I’ve done so far (simplified):
var ViewModel = function() {
var self = this;
self.objects = ko.observableArray(Objects);
};
Now I need to render those objects in different lists depending on their “type”. So there is a list of objects of type “A” and one for the objects of type “B” etc. (there are five types at the moment, but there may be added some more in the future).
I’ve come up with this (working) solution:
var ViewModel = function() {
var self = this;
self.objects = ko.observableArray(Objects);
self.objectsA = ko.computed(function() {
return ko.utils.arrayFilter(self.objects(), function(item) {
return (item.type == 'A');
});
});
self.objectsB = ...
self.objectsC = ...
};
And in my actual view:
<h1>Type A</h1>
<ul class="typeA" data-bind="template: { name: 'object', foreach: objectsA }"></ul>
<h1>Type B</h1>
<ul class="typeB" data-bind="template: { name: 'object', foreach: objectsB }"></ul>
Is there a better way to address this problem? This works, but it is a bit ugly, not really dynamic and includes a lot of repetition.
Bindings are executed inside of a
computed observable. This means that you can choose to use a simple function that takes a parameter rather than an actualcomputed observableif you would like.This means that you can simplify it down to:
Then, bind against it like:
Your UI will update now whenever the array is manipulated (items added/removed). However, if you are going to be editing the
typeon the fly, thentypewould need to be an observable for the computed observable to update (in your original method or in this way).Sample here: http://jsfiddle.net/rniemeyer/NFbxc/