首先,jsfiddle链接http://jsfiddle.net/wenbert/m5pHs/36/
<button data-bind="click: addHero">Add Hero With Meta</button>
<ul data-bind="foreach: heroes">
<li class="parent" data-bind="ifnot: isDeleted">
<input class="big-box" type="text" data-bind="value: name" />
<button class="btn-small" data-bind="click: $parent.removeHero">Remove Hero</button>
<br/>
<button class="btn-small" data-bind="click: $parent.addMeta">Add Meta</button>
<div class="child" data-bind="template: { name: 'checkbox-template' }"></div>
</li>
</ul>
<script type="text/html" id="checkbox-template">
<ul data-bind="foreach: meta">
<li data-bind="ifnot: isDeleted">
<input class="child-item blue" type="text" data-bind="value: name" />:
<input class="child-item small" type="text" data-bind="value: damage" />
<button class="btn-small" data-bind="click: $parent.removeMeta">Remove Meta</button>
<br/>
</li>
</ul>
</script>
<pre data-bind="text: ko.toJSON($data, null, 2)"></pre>
Javascript
var initialData = [
{
name: "Batman",
isDelete: false,
meta: [
{ name: "Belt", damage: "99", isDeleted: false },
{ name: "Gun", damage: "104", isDeleted: false}
]
},
{
name: "Hulk",
isDelete: false,
meta: [
{ name: "Pants", damage: "1", isDeleted: false }
]
},
];
function Hero(data) {
var self = this;
self.name = ko.observable(data.name);
self.meta = ko.observableArray(data.meta);
self.isDeleted = ko.observable(data.isDeleted);
}
function Meta(data) {
var self = this;
self.name= ko.observable(data.name);
self.damage= ko.observable(data.damage);
self.isDeleted = ko.observable(data.isDeleted);
}
function SuperheroViewModel() {
var self = this;
self.heroes = ko.observableArray();
self.heroes.meta = ko.observableArray();
self.heroes.push(new Hero(initialData[0]));
self.heroes.push(new Hero(initialData[1]));
self.addHero = function() {
self.heroes.push(
new Hero({
name: 'Wolverine',
isDelete: false,
meta: [new Meta({name: 'Claws', damage: '200', isDeleted: false})]
})
);
/*
//Using something like this also does not enable me to update the child items when adding.
self.heroes.push(new Hero(initialData[1])
);*/
}
self.addMeta = function(item) {
item.meta.push(new Meta({name: '--', damage: '0', isDeleted: false}));
}
self.removeHero= function(item) {
item.isDeleted(true);
}
self.removeMeta = function(item) {
item.isDeleted(true);
}
}
ko.applyBindings(new SuperheroViewModel());
看起来像什么
什么有效:
isDeleted
设置为true)什么行不通:
meta.isDeleted
设置为true 疑难杂症
所以2个问题:
更新:似乎子项目未更新,因为它们是使用initialData array
添加的。
谢谢!
答案 0 :(得分:3)
好的,请考虑this fiddle中的更改,这些更改有效,我认为更清晰。
我会打破我所做的事情
首先,我通过viewmodels构造函数传递data
,以便它可以重用:
ko.applyBindings(new SuperheroViewModel(initialData));
接下来,使用地图构造heroes
数组,这样无论传入数据的大小如何,它都会填充:
self.heroes = ko.observableArray(ko.utils.arrayMap(data, function(i){
return new Hero(i);
}));
我还将meta
构造移动到了英雄对象中,因为meta
是heroes
的子项,而不是根视图模型:
self.meta = ko.observableArray(ko.utils.arrayMap(data.meta, function(i){
return new Meta(i);
}));
由于hero
构造函数处理meta
构造,addHero
函数不再需要,因此其meta
行看起来与initialData行相同:
meta: [{name: 'Claws', damage: '200', isDeleted: false}]
最后,我将add/remove
元函数移动到hero
视图模型中。这更有意义,它解决了尝试使用$parent
中meta
的范围问题。
如果您有任何问题,请与我们联系。