KnockoutJS是否有功能,而我可以采取类似的方式:
var myArray = ko.observableArray([
{ name: "Jimmy", type: "Friend" },
{ name: "George", type: "Friend" },
{ name: "Zippy", type: "Enemy" }
]);
然后在“type”字段中选择distinct,产生如下所示的结果:
(pseudo code)
var distinct = myArray.distinct('type')
// Returns array of two arrays
// distinct[0] is an array of type=Friend
// distinct[1] is an array of type=Enemy
我知道ko.utils.arrayGetDistinctValues,但这并不完全符合我的要求。我也知道我可以使用ko.utils.arrayGetDistinctValues写几个循环来得到我想要的东西,我只是想知道是否还有其他东西被KnockoutJS烘焙,我忽略了。
答案 0 :(得分:34)
KO中没有任何其他内容可以让这更容易。
您可以通过多种方式开展此项工作。例如,您可以将observableArrays扩展为具有distinct
函数。然后,您可以创建observableArray,如:
this.people = ko.observableArray([
new Person("Jimmy", "Friend"),
new Person("George", "Friend"),
new Person("Zippy", "Enemy")
]).distinct('type');
distinct
功能可能如下所示:
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;
};
它支持链接,因此您可以使用不同的属性多次调用distinct
。
此处示例:http://jsfiddle.net/rniemeyer/mXVtN/
这会在每次更改时重建索引一次,因此如果您有大量项目,那么您可能希望探索其他方式(手动订阅)来添加/删除“索引”数组中的项目。
答案 1 :(得分:7)
我在jsfiddle中简化了RP Niemeyer的版本,不使用distinct函数。请参阅此处:jsfiddle
<ul data-bind="foreach: choices">
<li>
<h2 data-bind="text: $data"></h2>
<ul data-bind="foreach: $root.people">
<!-- ko if: $parent === type() -->
<li data-bind="text: name"></li>
<!-- /ko -->
</ul>
<hr/>
</li>
var Person = function(name, type) {
this.name = ko.observable(name);
this.type = ko.observable(type);
}
var ViewModel = function() {
var self = this;
this.choices = ["Friend", "Enemy", "Other" ];
this.people = ko.observableArray([
new Person("Jimmy", "Friend"),
new Person("George", "Friend"),
new Person("Zippy", "Enemy")
]);
this.addPerson = function() {
self.people.push(new Person("new", "Other"));
};
this.removePerson = function(person) {
self.people.remove(person);
};
};
ko.applyBindings(new ViewModel());
谢谢Niemeyer。
答案 2 :(得分:3)
只是想补充一点,如果你调用这个.distinct()
方法两次(比如可能来自一个计算的observable),你会得到两次调用的索引和相关的计算函数 - 冲洗和重复你就得到了你的手上出现了性能问题。
要对此进行排序,请在函数顶部附近添加此行:
if (target.index && target.index[prop]) return target; //Group by already set up, bail out.