我对KO相对比较陌生(两天前开始),并尝试了一些简单的例子。目前,我对这段代码有问题。
<div id="idChangeStyle">
<span data-bind="style: { background: GetAge() < 18 ? 'red':'white'}">Enter Your Age:</span>
<input type="text" data-bind="value: GetAge"></input>
</div>function ageViewModel() {
var self = this;
self.age = ko.observable(18);
self.GetAge = ko.computed({
read: function () {
return self.age();
},
write: function (value) {
value = parseInt(String(value).replace(/[^\d]/g, ""));
if (isNaN(value))
self.age(18);
else
self.age(value);
}
});
};
ko.applyBindings(new ageViewModel(), document.getElementById('idChangeStyle'));http://jsfiddle.net/WJZqj/
基本上,应用程序只接受一个输入(年龄)。我使用writable computed observable将输入解析为整数,并在解析其年龄后,尝试将年龄设置为默认值,即18。此外,我在NaN上有一个简单的逻辑,如果年龄小于18,则将跨度的背景更改为红色。
在正常情况下,它工作得很好,下面是我遇到问题的时候:
Case 1:
Current Input: 18 (initial case)
enter *4* then tab //works
enter *a* then tab //work (defaults to 18)
enter *a* then tab //doesn't work
case 2:
current input: 18
enter *a *then tab* //*doesn't work我检查了knockout的代码,看看在运行以下代码时会发生什么:
if(isNaN(value))
self.age(18);。。在以下行中:-
// Ignore writes if the value hasn't changed
if ((!observable['equalityComparer']) || !observable['equalityComparer'](_latestValue, arguments[0])) { _latestValue和arguments[0]都有相同的值(18),所以它什么也不做。由于年龄值现在没有变化,视图模型属性和UI不同步。
这是因为我做错了吗?
发布于 2013-03-27 06:08:03
问题是,如果你为一个可观察对象输入相同的值,它不会认为这是值的变化,也不会通知订阅者。如果您连续多次进入错误状态,则18最初将是设置的年龄,然后再次设置,不会发生任何更改事件。
也就是说,要解决这个问题,您必须手动通知订阅者。您可以通过在可观察对象上调用valueHasMutated()来简单地完成此操作。
self.GetAge = ko.computed({
read: function () {
return self.age();
},
write: function (value) {
value = parseInt(String(value).replace(/[^\d]/g, ""));
if (isNaN(value)) self.age(18);
else self.age(value);
self.age.valueHasMutated(); // notify subscribers
}
});发布于 2014-11-06 03:53:25
当我使用Knockout3.0.时,我也有同样的情况,但这些triks对我没有帮助,因为现在knockout只在计算属性值更改时通知。
我解决了这个问题: 1)只使用通知:always
function ageViewModel(data) {
//notify will should be always, because age is a primitive type
this.age = ko.observable(data.age).extend({notify: "always"});
this.GetAge = ko.computed({
read: function () {
// notify will should be always, because computed return values of a primitive type.
return this.age();
},
write: function (value) {
value = parseInt(String(value).replace(/[^\d]/g, ""));
if (isNaN(value)) {
this.age(18);
}
else this.age(value);
},
owner: this
}).extend({notify: "always"});
};2)使用notify:always和knockout.mapping
function ageViewModel(data) {
ko.mapping.fromJS(data, {}, this);
//notify will should be always, because age is a primitive type
this.age = this.age.extend({notify: "always"});
this.GetAge = ko.computed({
read: function () {
// notify will should be always, because computed return values of a primitive type.
return this.age();
},
write: function (value) {
value = parseInt(String(value).replace(/[^\d]/g, ""));
if (isNaN(value)) {
this.age(18);
}
else this.age(value);
},
owner: this
}).extend({notify: "always"});
};发布于 2013-03-27 05:34:38
解决这个问题的一个简单方法是将age设置为0,然后返回到默认值。
例如,更改为:
if(isNaN(value)) {
self.age(0);
self.age(18);
}我不知道什么是knockout才是“正确”的方式,但我可能会这么做。
https://stackoverflow.com/questions/15647767
复制相似问题