knockout - 如何在计算函数中使用模板数据

时间:2017-07-13 20:32:15

标签: templates knockout.js computed-field

目标是显示每个可能状态的已过滤项目列表。我正在尝试模板,因为这样的列表可能需要在很多地方显示。模板调用filterItems以获取其特定的项目列表。

下面的filterItems代码使用viewModel(current_filter)中的一个字段,因此所有列表都有相同的项目(3和8处于就绪状态):(这不是主意。每个模板实例都有$ data,包含正确的过滤器值。有没有办法让filterItems函数可以使用这个过滤器值?

<script>
var viewModel = {
items: ko.observableArray(
    [
        { "iid": 1, "state": "entered" },
        { "iid": 3, "state": "ready" },
        { "iid": 4, "state": "delivered" },
        { "iid": 8, "state": "ready" },
        { "iid": 13, "state": "entered" }
    ]),
states: ko.observableArray(
    [
        { "sid": 1, "filter": "entered", "color": "yellow" },
        { "sid": 2, "filter": "ready", "color": "red" },
        { "sid": 3, "filter": "delivered", "color": "blue" }
    ]),
current_filter: 'ready'
}
viewModel.filterItems = ko.computed(function () {
var filtered_items = [];
for (var i = 0; i < viewModel.items().length; ++i)
    if(viewModel.items()[i].state == viewModel.current_filter)
    filtered_items.push(viewModel.items()[i]);
return filtered_items;
}, viewModel);
</script>

<div data-bind="foreach: states">
  <div data-bind="template: {name: 'state', data: $data}"></div>
  <script type="text/html" id="state">
<h2 data-bind="text: filter"></h2>
<ul data-bind="foreach:viewModel.filterItems()">
  <li>
    <div data-bind="text: iid"></div>
  </li>
</ul>
  </script>
</div>
<script>ko.applyBindings(viewModel);</script>

jsFiddle https://jsfiddle.net/mthrock/kxpfdfva/8/#&togetherjs=JKJOos6VJc

1 个答案:

答案 0 :(得分:1)

组件而不是模板怎么样? 在下面运行代码段

ko.components.register('mycomponent', {
  viewModel: function(params) {
    var self = this;
    this.items = ko.observableArray(
      [{
        "iid": 1,
        "state": "entered"
      }, {
        "iid": 3,
        "state": "ready"
      }, {
        "iid": 4,
        "state": "delivered"
      }, {
        "iid": 8,
        "state": "ready"
      }, {
        "iid": 13,
        "state": "entered"
      }]);
    this.filter = params.filter;

    this.filterItems = ko.computed(function() {
      var filtered_items = [];
      for (var i = 0; i < this.items().length; ++i)
        if (this.items()[i].state == this.filter)
          filtered_items.push(this.items()[i]);
      return filtered_items;
    }, this);


  },
  template: ' <h2 data-bind="text: filter"></h2>\
   <ul data-bind="foreach:filterItems()">\
     <li>\
        <div data-bind="text: iid"></div>\
     </li>\
   </ul>'
});




function model() {
  var self = this;
  this.states = ko.observableArray(
    [{
      "sid": 1,
      "filter": "entered",
      "color": "yellow"
    }, {
      "sid": 2,
      "filter": "ready",
      "color": "red"
    }, {
      "sid": 3,
      "filter": "delivered",
      "color": "blue"
    }]);

}

var mymodel = new model();

$(document).ready(function() {
  ko.applyBindings(mymodel);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div data-bind="foreach: states">
  <mycomponent params="filter: filter"></mycomponent>
</div>