rom*_*n m 2 observable knockout.js
我有一个绑定到的文本框列表ko.observableArray.
我必须确保文本框值不能为空,并且我通过将值设置为0来实现,如果它是空白的 blur()
问题是使用jQuery完成的值更改未通过knockout注册.
如何观察模型中的值变化?
看看我简化的小提琴,以了解重点 - http://jsfiddle.net/k45gd/1/
HTML
<input type="number" data-bind="value: age" />
<span data-bind="text: age"></span>
<button data-bind="click: setAgeExternally">I want the label to change to 0</button>
Run Code Online (Sandbox Code Playgroud)
JS
var model = function() {
this.age = ko.observable(21);
//this code is outside of the model, this is oversimplification
this.setAgeExternally = function(){
$('input').val(0);
}
};
ko.applyBindings(new model());
Run Code Online (Sandbox Code Playgroud)
Mic*_*est 14
你需要两件事:
使用jQuery更改元素的值后,您需要让Knockout知道更新模型.您可以通过触发change事件来完成此操作:
$('input').val(0).trigger('change');
Run Code Online (Sandbox Code Playgroud)对于Knockout(在3.1.0之前)响应jQuery事件,它需要知道你正在使用jQuery.为此,您必须在Knockout之前在文档中包含jQuery.
这是两个更新的小提琴:http://jsfiddle.net/mbest/k45gd/2/
在您提供的示例中,您将使用以下代码更新输入框:
this.setAgeExternally = function(){
$('input').val(0);
}
Run Code Online (Sandbox Code Playgroud)
考虑到输入绑定到age属性,这样做会更简单:
this.setAgeExternally = function(){
this.age(0);
}
Run Code Online (Sandbox Code Playgroud)
但是,即使这不是真的需要,因为age属性在您的viewmodel上公开.所以外部代码可以这样做,并且实际上并不需要setAgeExternally方法:
model.age(0);
Run Code Online (Sandbox Code Playgroud)
让我们回到你原来的问题 - 你描述但不发布代码的问题.您提到您有一个绑定到可观察数组的输入框列表.
使用可观察数组时,您需要注意一个有趣的问题:
从http://knockoutjs.com/documentation/observableArrays.html上的文档:
关键点:observableArray跟踪数组中的对象,而不是这些对象的状态
简单地将对象放入observableArray并不会使该对象的所有属性本身都可观察到.当然,如果您愿意,您可以观察这些属性,但这是一个独立的选择.observableArray只跟踪它所拥有的对象,并在添加或删除对象时通知侦听器.
根据您列出的要求,根本不需要jQuery.您可以尝试以下三部分解决方案:
使您的observableArray包含observable.所以你最终得到的结果如下:
var model = function() {
this.ages = ko.observableArray([
{age: ko.observable(13)},
{age: ko.observable(18)},
{age: ko.observable(16)},
{age: ko.observable(13)}
]);
};
Run Code Online (Sandbox Code Playgroud)接下来,创建一个敲除扩展器,如果空白则自动重置为0
ko.extenders.defaultIfBlank = function(target, defaultValue) {
var result = ko.computed({
read: target, //always return the original observables value
write: function(newValue) {
if (newValue == "") {
target(defaultValue);
} else {
target(newValue);
}
}
});
//initialize with current value to make sure it is not blank
result(target());
//return the new computed observable
return result;
};
Run Code Online (Sandbox Code Playgroud)将扩展器应用于阵列中的observable
var model = function() {
this.ages = ko.observableArray([
ko.observable(13).extend({defaultIfBlank: "0"}),
ko.observable(18).extend({defaultIfBlank: "0"}),
ko.observable(16).extend({defaultIfBlank: "0"}),
ko.observable(13).extend({defaultIfBlank: "0"})
]);
};
Run Code Online (Sandbox Code Playgroud)工作小提琴:http://jsfiddle.net/tlarson/GF3Xe/