且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

KnockoutJS ObservableArray 数据分组

更新时间:2023-12-05 13:08:10

KO 中没有任何其他内容可以让这一切变得更容易.

您可以通过多种方式完成这项工作.例如,您可以扩展 observableArrays 以具有 distinct 函数.然后,你可以像这样创建你的 observableArray:

this.people = ko.observableArray([新人(吉米",朋友"),新人(乔治",朋友"),新人(Zippy",敌人")]).distinct('类型');

distinct 函数可能如下所示:

ko.observableArray.fn.distinct = function(prop) {var 目标 = 这个;target.index = {};target.index[prop] = ko.observable({});ko.computed(function() {//重建索引var propIndex = {};ko.utils.arrayForEach(target(), function(item) {var key = ko.utils.unwrapObservable(item[prop]);如果(键){propIndex[key] = propIndex[key] ||[];propIndex[key].push(item);}});target.index[prop](propIndex);});返回目标;};

它支持链接,因此您可以使用不同的属性多次调用 distinct.

示例:http://jsfiddle.net/rniemeyer/mXVtN/

这会在每次更改时重建索引一次,因此如果您有大量项目列表,那么您可能希望探索其他方式(手动订阅)从索引"数组中添加/删除项目.>

Does KnockoutJS have a feature whereas I could take something like:

    var myArray = ko.observableArray([
      { name: "Jimmy", type: "Friend" },
      { name: "George", type: "Friend" },
      { name: "Zippy", type: "Enemy" }
    ]);

Then select distinct on the "type" field, producing a result which looks like this:

(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 

I'm aware of ko.utils.arrayGetDistinctValues, but that doesn't exactly do what I want. I'm also aware that I could write a few loops using ko.utils.arrayGetDistinctValues to get what I want, I'm just wondering if there is something else baked into KnockoutJS that I'm overlooking.

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.