vki*_*kim 10 javascript knockout.js
请看看我的文字.我尝试使用oboutableArray of knockoutjs和foreach来计算数组的数据.示例1工作正常:如果更改字段中的数据,则计算总和.但是示例2不起作用.
<html>
<head>
<title></title>
<script type='text/javascript' src='/js/jquery-1.8.2.min.js'></script>
<script type='text/javascript' src='/js/knockout-2.1.0.debug.js'></script>
</head>
<body>
<p>Example 1</p>
<div>
<p>
<input data-bind="value: fnum1" />
<input data-bind="value: fnum2" />
<span data-bind="text: ftotsum"></span>
</p>
</div>
<p>Example 2</p>
<div>
<p>
<!-- ko foreach: fields -->
<input data-bind="value: $data" />
<!-- /ko -->
<span data-bind="text: ltotsum"></span>
</p>
</div>
</body>
<script>
function vm(){
//Calc Example 1
var self = this;
self.fnum1 = ko.observable(1);
self.fnum2 = ko.observable(2);
self.ftotsum = ko.computed(function(){
return parseFloat(self.fnum1()) + parseFloat(self.fnum2());
});
//Calc Example 2
self.fields = ko.observableArray([1, 2]);
self.ltotsum = ko.computed(function(){
var total = 0;
ko.utils.arrayForEach(self.fields(), function(item) {
total += parseFloat(item);
})
return total;
});
};
ko.applyBindings(new vm());
</script>
</html>
Run Code Online (Sandbox Code Playgroud)
编辑:小提琴工作,Raffaele说你需要将observable包装在一个对象中是正确的,但你可以在数组创建本身内完成它,我喜欢使用ko.utils来解开我的observable,它做同样的事情对于可观察的,但如果有一个不可观察的传递给它,它不会崩溃.请参阅小提琴以获取完整示例.
observableArray不会使值传递为可观察的,这是一个常见的错误.observableArray只观察对数组的修改而不是值.如果你想让你的数组中的值可观察,你必须这样做.
function vm(){
//Calc Example 1
var self = this;
self.fnum1 = ko.observable(1);
self.fnum2 = ko.observable(2);
self.ftotsum = ko.computed(function(){
return parseFloat(self.fnum1()) + parseFloat(self.fnum2());
});
//Calc Example 2
self.fields = ko.observableArray([{"num":ko.observable(1)},{"num":ko.observable(2)}]);
self.ltotsum = ko.computed(function(){
var total = 0;
ko.utils.arrayForEach(self.fields(), function(item) {
total += parseFloat(ko.utils.unwrapObservable(item.num));
});
return total;
});
};
ko.applyBindings(new vm());
Run Code Online (Sandbox Code Playgroud)
现在应该使用上面的例子.
该文件说:
关键点:
observableArray跟踪哪些对象在数组中,而不是那些对象的状态简单地将对象放入observableArray并不会使该对象的所有属性本身都可观察到.当然,如果您愿意,您可以观察这些属性,但这是一个独立的选择.observableArray只跟踪它所拥有的对象,并在添加或 删除对象时通知侦听器.
您的第二个示例不起作用,因为输入字段的值未绑定到数组中的值.数组中的值仅在foreach绑定中使用一次,但是当您在输入框中键入时,没有任何内容触发KO.
这是一个实施解决方案的工作小提琴.我用了一个帮手ObsNumber
function vm(){
var self = this;
var ObsNumber = function(i) {
this.value = ko.observable(i);
}
self.fields = ko.observableArray([new ObsNumber(1) ,
new ObsNumber(2)]);
self.sum = ko.computed(function(){
var total = 0;
ko.utils.arrayForEach(self.fields(), function(item) {
total += parseFloat(item.value());
});
return total;
});
};
ko.applyBindings(new vm());
Run Code Online (Sandbox Code Playgroud)
和以下标记
<div>
<p>
<!-- ko foreach: fields -->
<input data-bind="value: $data.value" />
<!-- /ko -->
<span data-bind="text: sum"></span>
</p>
</div>?
Run Code Online (Sandbox Code Playgroud)