Knockout JS使用JSON迭代一个对象数组

时间:2018-01-21 17:29:07

标签: javascript arrays json knockout.js

以下是我的JSON回复。我需要使用knockout foreach遍历这个数组并将此数组显示为手风琴。在这种情况下,“Nissan”将成为手风琴的标题并点击它展开以显示其他细节。我找不到打印键的方法(“日产”或“福特”)并正确创建一个手风琴。它将是一个动态数组,键将是不同的。我想我需要嵌套的foreach并在迭代第二个时遇到问题。提前致谢。

  var ViewModel = function() {
    var self = this;
    this.entries =
       {
        "Nissan": [
            {"model":"Sentra", "doors":4},
            {"model":"Maxima", "doors":4}
        ],
        "Ford": [
            {"model":"Taurus", "doors":4},
            {"model":"Escort", "doors":4}
        ]
}
    ;


<table>
<tbody data-bind="foreach: entries">
    <tr>
        <td data-bind="foreach: $parent.data()">
            <a href="#" data-bind="text: model"></a>
        </td>
    </tr>
</tbody>
</table>

Fiddle

1 个答案:

答案 0 :(得分:0)

JSON数据使用对象将品牌映射到模型阵列,即“Nissan” - &gt; [...],“福特” - &gt; [...]。当通常处理这种数据时,我使用ko.computed()将对象映射转换为对象数组,通常添加必要的函数和observable。

我使用嵌套列表而不是表格发布了JSFiddle here。点击该品牌可扩展/折叠汽车模型的子列表。

<ul data-bind="foreach: entries">
  <li>
    <a href="javascript:void(0)" data-bind="text: brand, click: toggle"></a>
    <ul data-bind="foreach: models, visible: visible">
      <li data-bind="text: model"></li>
    </ul>
  </li>
</ul>

此外,在迭代对象的属性时,无法保证顺序。在下面的代码中,列表已排序以确保顺序一致。最佳做法是使用hasOwnProperty检查属性是否在对象上,并且在将对象用作地图时不会从原型链继承。

另请注意,我将JSON响应粘贴到observable中,然后生成计算的observable中的条目列表。这确保了如果设置了新的JSON数据,则计算的observable将自动更新。

var ViewModel = function() {
var self = this;
self.cars = ko.observable({
  "Nissan": [{
    "model": "Sentra",
    "doors": 4
  }, {
    "model": "Maxima",
    "doors": 4
  }],
  "Ford": [{
      "model": "Taurus",
      "doors": 4
    }, {
      "model": "Escort",
    "doors": 4
  }]
});
self.entries = ko.computed(function() {
  var list = [],
  entryVM,
  data = self.cars();
  for (var brand in data) {
    if (data.hasOwnProperty(brand)) {
      entryVM = new EntryViewModel(brand, data[brand]);
      list.push(entryVM);
    }
  }
  return list.sort(function(a, b) {
    if (a.brand < b.brand) {
      return -1;
    }
    if (a.brand > b.brand) {
      return 1;
    }
    return 0;
  });
});
};

对于每个条目,都会创建一个单独的视图模型EntryViewModel,它封装了值和交互。在这种情况下,切换模型列表的可见性被封装在内部视图模型中,因此主视图模型不需要关注内部视图模型的状态。

var EntryViewModel = function(brand, models) {
  var self = this;
  self.brand = brand;
  self.models = models;
  self.visible = ko.observable(false);
  self.toggle = function() {
    self.visible(!self.visible());
  }

};