如何使用KnockOut JS对组进行排序

时间:2017-12-06 19:01:49

标签: javascript knockout.js

我将使用KnockOut JS对每个组中的每个项目进行排序。但是,只有小组工作,排序并没有像我期望的那样工作。请使用comment lines查看下面的代码,并将您的想法或任何指南分享给我。

CSS:

.displayTable {
  display: table;
  border: 1px solid black;
  border-collapse: collapse;
  width: 100px;
}

.displayRow {
  display: table-row;
}

.displayCell {
  display: table-cell;
  border: 1px solid black;
}

.displayCell.age,
.displayCell.section {
  width: 50px;
}

HTML:

<div class="displayTable" data-bind="foreach: choices">
  <div class="displayRow">
    <div class="displayCell" data-bind="text: $data"></div>
    <div class="displayCell">Age</div>
    <div class="displayCell">Phone</div>
  </div>
  <div class="displayRow" data-bind="foreach: $root.people.index.type()[$data]">
    <div class="displayTable">
      <div class="displayRow">
        <div class="displayCell" data-bind="text: name"></div>
        <div class="displayCell" data-bind="text: age"></div>
      </div>
    </div>
  </div>
</div>

JS:

ko.observableArray.fn.distinct = function(prop, sort) {
  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]);
      propIndex[key] = propIndex[key] || [];
      propIndex[key].push(item);
    });

        // Sort by age in a group
    //propIndex[key].sort(function(l, r) {
    //  return l.age == r.age ? 0 : (l.age < r.age ? -1 : 1);
    //});

    target.index[prop](propIndex);
  });

  return target;
};

var Person = function(name, type, age) {
  this.name = ko.observable(name);
  this.type = ko.observable(type);
  this.age = ko.observable(age);
}

var ViewModel = function() {
  var self = this;
  this.choices = ["Friend", "Enemy", "Other"];
  this.people = ko.observableArray([
    new Person("Jimmy", "Friend", 35),
    new Person("George", "Friend", 40),
    new Person("Mike", "Friend", 30),
    new Person("Zippy", "Enemy", 20)
  ]).distinct('type', 'sort');

  this.addPerson = function() {
    self.people.push(new Person("new", "Other", 0));
  };

  this.removePerson = function(person) {
    self.people.remove(person);
  };
};

ko.applyBindings(new ViewModel());

结果必须是:

Friend:
George  40
Jimmy   35
Mike    30

Friend:
Mike    30
Jimmy   35
George  40

它也在所有其他群体中排序。

这是我的JS Fiddle

1 个答案:

答案 0 :(得分:0)

您尝试排序的索引是对象词典而不是数组,因此您必须使用属性枚举器循环它们。此外,您要排序的属性,&#34;年龄&#34;在你的样本中,是可观察的,必须用括号或ko.unwrap取消装箱,如果它们不能被观察到。

如果你想使用传入的排序值来确定要排序的属性,我会在构建propIndex对象的循环之后执行以下操作。

// Sort within groups
for(var i in propIndex){
  if(propIndex.hasOwnProperty(i)){
    propIndex[i].sort(function(l, r) {
      return ko.unwrap(l[sort]) == ko.unwrap(r[sort]) ? 0 : (ko.unwrap(l[sort]) < ko.unwrap(r[sort]) ? -1 : 1);
    });
  }
}