Alb*_*reo 4 observer-pattern knockout-mapping-plugin knockout.js
我遇到了Knockout映射插件的一个奇怪问题.
如果我通过映射填充可观察数组,我无法迭代数组或获取其长度,即使UI正确更新,数组似乎是空的.
你可以在这里找到一个有用的jsFiddle:http://jsfiddle.net/VsbsC/
这是HTML标记:
<p><input data-bind="click: load" type="button" value="Load" /></p>
<p><input data-bind="click: check" type="button" value="Check" /></p>
<table>
<tbody data-bind="foreach: items">
<tr>
<td data-bind="text: name"></td>
<td data-bind="text: value"></td>
</tr>
</tbody>
</table>
<p data-bind="text: total"></p>
Run Code Online (Sandbox Code Playgroud)
这是JavaScript代码:
var ViewModel = function () {
var self = this;
self.items = ko.observableArray();
self.load = function () {
self.items([
{ "name": "joey", "value": 1 },
{ "name": "anne", "value": 2 },
{ "name": "paul", "value": 3 },
{ "name": "mike", "value": 4 }
]);
};
self.check = function () {
alert(self.items().length);
};
self.total = ko.computed(function () {
var total = 0;
for (var i = 0; i < self.items().length; i++) {
total += self.items()[i].value;
}
return total;
});
};
var viewModel = new ViewModel();
ko.applyBindings(viewModel);
Run Code Online (Sandbox Code Playgroud)
当我单击" 加载"按钮时,记录和总数都会正确显示,当我单击" 检查"按钮时,我会得到正确的项目编号.
但是,如果我改变了
self.items([
{ "name": "joey", "value": 1 },
{ "name": "anne", "value": 2 },
{ "name": "paul", "value": 3 },
{ "name": "mike", "value": 4 }
]);
Run Code Online (Sandbox Code Playgroud)
至
self.items(ko.mapping.fromJS([
{ "name": "joey", "value": 1 },
{ "name": "anne", "value": 2 },
{ "name": "paul", "value": 3 },
{ "name": "mike", "value": 4 }
]));
Run Code Online (Sandbox Code Playgroud)
UI仍然可以正确呈现,但总数显示为零,单击Check也产生零,并且console.info-ing self.items产生一个空数组.
这怎么可能?我无数次重读这些教程,我无法理解我做错了什么.
Ps我需要通过映射插件填充可观察数组,因为在真实页面中,值来自AJAX请求.
RP *_*yer 11
您看到的问题是基于如果给定数组,映射插件将创建observableArray的事实.因此,您将self.itemsobservableArray 的值设置为等于observableArray(而不仅仅是数组).所以,这是一个额外的时间.
这是一种方法:
var ViewModel = function () {
var self = this;
self.items = ko.mapping.fromJS([]);
self.load = function () {
ko.mapping.fromJS([
{ "name": "joey", "value": 1 },
{ "name": "anne", "value": 2 },
{ "name": "paul", "value": 3 },
{ "name": "mike", "value": 4 }
], self.items);
};
self.check = function () {
alert(self.items().length);
};
self.total = ko.computed(function () {
var total = 0, items = self.items();
for (var i = 0; i < items.length; i++) {
total += items[i].value();
}
return total;
});
};
var viewModel = new ViewModel();
ko.applyBindings(viewModel);
Run Code Online (Sandbox Code Playgroud)
因此,您使用映射插件初始化原始的observableArray,因此可以更新它.然后,在更新时ko.mapping.fromJS,使用更新的数据和要更新的映射对象进行调用.
此时的另一个微小变化就是value()在你的计算observable中使用,因为它是一个可以从映射插件中观察到的.
此处示例:http://jsfiddle.net/rniemeyer/3La5K/
| 归档时间: |
|
| 查看次数: |
5062 次 |
| 最近记录: |