【发布时间】:2014-03-26 05:29:05
【问题描述】:
我在使用映射插件的淘汰赛中遇到了嵌套视图模型的一些问题。我能够重现这个问题,我在这里为它创建了一个小提琴:Fiddle
我已经剥离了实际的视图和视图模型,所以不要期望输出看起来不错,但它会得到消息。这是我的看法:
<div data-bind="foreach: $root.selectedArmy().Units">
<div class="unitoverview">
<!-- ko foreach: UnitMembers-->
<div class="member">
<div>
<span class="name" data-bind="text: Name, click: $parent.RemoveTest"></span>
</div>
<div data-bind="foreach: test">
<span data-bind="text:$data, click: $parent.RemoveTest"></span>
</div>
<h1 data-bind="text: test2"></h1>
</div>
<!-- /ko -->
</div>
</div>
<span data-bind="click:AddUnit">CLICK TO ADD UNIT</span>
这是我的模型:
var armymaker = armymaker || {};
var unitMapping = {
'UnitMembers': {
create: function (options) {
return new UnitMemberViewModel(options.data);
}
}
};
var UnitViewModel = function (unit) {
var self = this;
self.Name = ko.observable("unitname");
self.UnitDefinitionId = ko.observable(unit.Id);
ko.mapping.fromJS(unit, {}, self);
};
var UnitMemberViewModel = function (unitmemberdefinition) {
var self = this;
self.test = ko.observableArray([ko.observable('TEST'), ko.observable('TEST2')]);
self.test2 = ko.observable('TEST1');
self.RemoveTest = function () {
self.test.splice(0,1);
self.Name('BUGFACE');
self.test2('OKI!!');
};
ko.mapping.fromJS(unitmemberdefinition, {}, self);
};
var ViewModel = function () {
var self = this;
self.showLoader = ko.observable(false);
self.newArmy = ko.observable({});
self.unitToAdd = ko.observable(null);
self.selectedArmy = ko.observable({ Template: ko.observable(''), Units: ko.observableArray() });
self.AddUnit = function () {
var data = {'Name': 'My name', 'UnitMembers': [
{ 'Name': 'Unitname1' }
] };
self.unitToAdd(new UnitViewModel((ko.mapping.fromJS(data, unitMapping))));
self.selectedArmy().Units.push(self.unitToAdd());
self.unitToAdd(null);
};
};
armymaker.viewmodel = new ViewModel();
ko.applyBindings(armymaker.viewmodel);
会发生以下情况:
我单击链接 CLICK TO ADD UNIT,并创建了一个 UnitViewModel,对于 UnitMember 数组中的每个元素,由于我是自定义活页夹 (unitMapper),它将使用 UnitMemberViewModel使用。
这一切似乎工作正常。但是在最里面的视图模型中,我向数据模型添加了一些字段。我称他们为test,即observableArray,test2,即普通observable。我还创建了一个名为RemoveTest 的方法,该方法在视图中绑定到表示test2 的跨度和表示数组test 的每个元素的foreach 中的跨度。
但是,当我调用该方法时,对 observable 的更改会反映在视图中,但对 observableArray 的更改在视图中不可见。详情请查看小提琴。
是否有任何原因导致对 obsArray 的更改在视图中不可见,但对普通 observable 的更改会?
我做了一些观察:
-
observable上的点击事件不起作用,只有observableArray上的元素的点击事件。 - 点击事件中的self似乎与实际的viewmodel不匹配。如果我去
self.test.splice(0,1)视图中没有任何反应,但self.test.splice在该命令之后只包含一个元素。但是,如果我遍历基本视图模型 (armymaker.viewmodel.Units()[0].UnitMembers()[0].test) 仍然包含两个元素。 - 在遍历的视图模型 (
armymaker.viewmodel.Units()[0].UnitMembers()[0].test.splice(0,1)) 上调用 splice 会从视图中移除元素,因此从某种意义上说,self 引用的元素与视图内链接的元素不是同一个对象。但是,为什么它对不是array的observable有效?
我的模型可能存在缺陷,但我看不到它,因此我希望能得到一些帮助。
【问题讨论】:
标签: javascript knockout.js knockout-mapping-plugin ko.observablearray