2013-07-24 20 views
2

我需要一个时间戳来更新值。由于我不想进入这里的原因,value是一个可写的计算结果,指向一个valueInstance观测值,所以它们基本上显示相同的数据。Knockout订阅正在意料之外的评估

如果我订阅observable,它按预期工作,只有当observable发生变化时才会触发。如果我订阅了计算器,它立即引发一个错误的时间戳,即使observable仍未定义。这是怎么回事?

http://jsfiddle.net/bNXhm/

更新:看起来像当计算这只是发生了deferEvaluation: true

http://jsfiddle.net/bNXhm/1/

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

什么是你的问题?我没有看到任何意外的行为。 – Damien

+0

即使'value'没有改变,'value.subscribe'也会在初始加载时触发。订阅应该只在值更改时触发。 – Homer

回答

1

当您创建一个observable时,除非将deferEvaluation设置为true,否则它将被评估。 当可观察(或计算)的评估时,它总是通知他们的用户。在这一点上没有与之前的值进行比较(只有当值改变时才通知)。

“无用通知检查”是在observable的setter中进行的。

因此,在您的代码中,当您使用deferEvaluation为false时,将立即评估读取函数,并且会通知订阅者。但目前没有订户。这就是为什么没有设定时间跨度。

当您使用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; 

我希望它能帮助

See fiddle

1

当你deferEvalaution的计算不计算,直到有人请求它的价值。这发生在绑定时。评估时,它会通知任何订户。这可以解释为什么您的订阅受到影响。