There is not anything else built into KO to make this any easier.
There are many ways that you could make this work. For example, you could extend observableArrays to have a distinct
function. Then, you can just create your observableArray like:
this.people = ko.observableArray([
new Person("Jimmy", "Friend"),
new Person("George", "Friend"),
new Person("Zippy", "Enemy")
]).distinct('type');
The distinct
function might look like:
ko.observableArray.fn.distinct = function(prop) {
var target = this;
target.index = {};
target.index[prop] = ko.observable({});
ko.computed(function() {
//rebuild index
var propIndex = {};
ko.utils.arrayForEach(target(), function(item) {
var key = ko.utils.unwrapObservable(item[prop]);
if (key) {
propIndex[key] = propIndex[key] || [];
propIndex[key].push(item);
}
});
target.index[prop](propIndex);
});
return target;
};
It supports chaining so you could call distinct
multiple times with different properties.
Sample here: http://jsfiddle.net/rniemeyer/mXVtN/
This does rebuild the index once on each change, so if you have a huge list of items, then you would want to potentially explore other ways (manual subscriptions) for adding/removing items from the "index" arrays.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…