根据匹配的项属性添加类别行

时间:2014-01-21 12:54:55

标签: javascript knockout.js

我有一个用KO显示的已排序的静态列表,并希望在类别更改时显示类别标题(因为列表按类别排序)。我还在兴起KO,这是“KO”这样做的方式,还是有更好的方法?特别是访问列表中前一项的语法有点毛茸茸,这让我怀疑我错过了一项可以改善这一点的功能。 : - )

Live Copy | Source

HTML:

<table>
  <tbody data-bind="foreach: items">
    <!-- ko if: $index() === 0 || $parent.items()[$index() - 1].category() !== category() -->
    <tr class="category">
      <td colspan="2" data-bind="text: category"></td>
    </tr>
    <!-- /ko -->
    <tr>
      <td data-bind="text: item"></td>
      <td class="num" data-bind="text: quantity"></td>
    </tr>
  </tbody>
</table>

JavaScript:(显然这只是一个快速而又脏的虚拟机)

function Item(category, item, quantity) {
    this.category = ko.observable(category);
    this.item = ko.observable(item);
    this.quantity = ko.observable(quantity);
}

var vm = {
    items: ko.observableArray([
        new Item("Fruit", "Apples", 27),
        new Item("Fruit", "Oranges", 17),
        new Item("Fruit", "Kiwis", 3),
        new Item("Vegetables", "Celery", 16),
        new Item("Vegetables", "Carrots", 72),
        new Item("Sundries", "Toothpaste", 10),
        new Item("Sundries", "Washing-up liquid", 8)
    ])
};
ko.applyBindings(vm, document.body);

结果:(有些琐碎的CSS不相关)

Table with category rows

2 个答案:

答案 0 :(得分:4)

如果您修改了可观察数组并将其构造为包含具有关联数量的项目数组,则可以执行以下操作:

<强> JS:

function Item(category, itemList) {
    this.category = ko.observable(category);
    this.itemList = ko.observableArray(itemList);

}

var vm = {
    items: ko.observableArray([
        new Item("Fruit", [{"item": "Apples", "qty": 27 }, 
                           {"item": "Oranges", "qty": 17}, 
                           {"item": "Kiwis", "qty": 3}]),              
        new Item("Vegetables", [{"item": "Celery", "qty": 16},
                                {"item": "Carrots", "qty": 72}]),      
        new Item("Sundries", [{"item": "Toothpaste", "qty": 10},
                              {"item": "Washing-up liquid", "qty": 8}]),    
    ])
};

ko.applyBindings(vm, document.body);

<强> HTML:

<table>
  <tbody data-bind="foreach: items">    
    <tr class="category">
      <td colspan="2" data-bind="text: category"></td>
    </tr>
    <!-- ko foreach: itemList -->
        <tr>
          <td data-bind="text: item"></td>
          <td class="num" data-bind="text: qty"></td>
        </tr>
    <!-- /ko -->    
  </tbody>
</table>

请在此处查看JSFiddle:http://jsfiddle.net/y4yPv/2/

答案 1 :(得分:2)

您可以在项目中添加categoryId,然后按类别进行排序。它使您可以分离简单项目和类别的项目:

HTML:

<table>
    <tbody data-bind="foreach: items">
        <!-- ko if: type == 0 -->
        <tr class="category">
            <td colspan="2" data-bind="text: item"></td>
        </tr>
        <!-- /ko -->
        <!-- ko if: type == 1 -->
        <tr>
            <td data-bind="text: item"></td>
            <td class="num" data-bind="text: quantity"></td>
        </tr>
        <!-- /ko -->
    </tbody>
</table>

视图模型:

function Item(type, categoryId, item, quantity) {
    this.type = type;
    this.categoryId = categoryId;
    this.item = ko.observable(item);
    this.quantity = ko.observable(quantity);
}

var vm = {
    items: ko.observableArray([
        new Item(0, 1, "Fruit"), 
        new Item(1, 1, "Apples", 27),
        new Item(1, 1, "Oranges", 17),
        new Item(1, 1, "Kiwis", 3),
        new Item(0, 2, "Vegetables"),
        new Item(1, 2, "Celery", 16),
        new Item(1, 2, "Carrots", 72),
        new Item(0, 3, "Sundries"),
        new Item(1, 3, "Toothpaste", 10),
        new Item(1, 4, "Washing-up liquid", 8)
    ])
};
ko.applyBindings(vm, document.body);