我需要一个时间戳来更新值。由于我不会进入这里的原因,value
是一个可写的计算指向valueInstance
可观察的,因此它们基本上显示相同的数据。
如果我订阅了observable它按预期工作,只有在observable发生变化时才会触发。如果我订阅了计算它会立即触发导致错误的时间戳,即使observable仍未定义。怎么了?
更新:看起来只有在计算出的deferEvaluation: true
function VM(){
var self = this;
self.valueInstance = ko.observable();
self.value = ko.computed({
read: function () {
return self.valueInstance();
},
write: function (value) {
self.valueInstance(value);
},
deferEvaluation: true
});
self.timeStamp1 = ko.observable();
self.value.subscribe(function (newValue) {
self.timeStamp1(new Date());
});
self.timeStamp2 = ko.observable();
self.valueInstance.subscribe(function (newValue) {
self.timeStamp2(new Date());
}); }
答案 0 :(得分:1)
当deferEvalaution
计算出来时,在有人请求其值之前,不会对其进行评估。绑定时会发生这种情况。在评估时,它会通知任何订户。这可以解释为什么您的订阅被点击。
答案 1 :(得分:1)
创建observable时,除非将deferEvaluation设置为true,否则将对其进行评估。 当评估可观察(或计算)时,它总是通知它们订户。此时没有与之前的值进行比较(仅在值发生变化时才通知)。
“无用的通知检查”是在observable的setter中进行的。
因此,在您的代码中,当您在false时使用deferEvaluation时,会立即评估read函数并通知订阅者。但目前没有订阅者。这就是为什么没有设定时间跨度的原因。
当您使用deferEvaluation:true时,评估过程是applyBindings函数的延迟。此时您已经订阅了,这就是设置时间跨度的原因。
要解决您的问题,我会在您应该开始记录更改时创建一个存储变量。
function VM(){
var self = this;
self.logged = false;
self.valueInstance = ko.observable();
self.value = ko.computed({
read: function () {
return self.valueInstance();
},
write: function (value) {
self.valueInstance(value);
},
deferEvaluation: true
});
self.timeStamp1 = ko.observable();
self.value.subscribe(function (newValue) {
if(self.logged)
self.timeStamp1(new Date());
});
self.timeStamp2 = ko.observable();
self.valueInstance.subscribe(function (newValue) {
if(self.logged)
self.timeStamp2(new Date());
});
}
var vm = new VM();
ko.applyBindings(vm);
vm.logged = true;
我希望它有所帮助