以下是我的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>
答案 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());
}
};