2013-12-13 20 views
3

内部正在执行Knockout js订阅函数(对于observable)。我已经在我的一个可观察对象上获得了一个订阅函数。我假定只有当它的可观察对象发生变化时,才会执行订阅函数。尽管当我追踪我的代码时,我可以看到它在初始化时调用ko.applyBindings(MyViewModel);后正在执行。ko.applyBindings(...)

以下是我已经得到了我的ViewModel:

function MyViewModel(myModel){ 
    this.myProperty = ko.observable(myModel.myProperty); 

    this.myProperty .subscribe(function (val) { 
     // do sth.. 
    }, this); 
} 

,这是我打这个电话给applyBindings:

jQuery(document).ready(
    function ($) { 
     ko.applyBindings(MyViewModel); 
}); 

这是一个预期的行为?

订阅功能正在ko.applyBindings(MyViewModel);之后被调用,这意味着我在此期间没有从UI获取任何输入。

我希望拥有它,所以只要myProperty的值发生更改,它就只执行我的订阅函数体。有没有办法让我跟踪我的可观察对象,看看发生了什么变化?

+4

订阅只会在值更改时运行。 applyBindings中的值可能会从写入其值的绑定中更改。你是否碰巧用'value'绑定了'select'属性,并且有一个初始数值被更新为一个字符串? –

+0

@RPNiemeyer:感谢您的有用评论。由于来自后端代码的一些变化,订阅实际上在初始化后被调用。正如你所提到的那样, – r2d2oid

回答

5

设置订阅时,当您调用ko.applyBindings()时,评估和触发订阅。

如果您只查看更改跟踪,则可以使用计算的可观察值并获得相同的结果。它看起来像你可以从ko.applyBindings正在评估推迟计算观察到的()加入{deferEvaluation:真正}如下选项:

例如:

function MyViewModel(myModel){ 
     this.myProperty = ko.observable('someValue'); 
     this.runCode = ko.computed(function (val) { 
      // do some stuff any time this.myProperty() is changed 
      console.log(this.myProperty()); 
     }, this, {deferEvaluation: true}); 
    } 

var vm = new MyViewModel(); 

ko.applyBindings(vm); 

vm.runCode(); 

vm.myProperty('some new value2'); 

这将防止默认行为在评估时执行代码。为了让它开始跟踪事件,当你想要开始跟踪时,你必须调用计算(在这种情况下是vm.runCode())。

继承人的更新小提琴,显示的行为:http://jsfiddle.net/amspianist/SL22M/2/

+0

也会在初始化时执行一次;所以它不会解决我的问题。尽管谢谢! – r2d2oid

+0

没问题。我只是想说明这是淘汰赛的正常行为。我在最近的一个项目中遇到了这个问题,并且基本上必须创建一个使用jQuery连接更改事件处理程序的函数。你是否试图追踪输入/表单元素的变化?或者其他一些JavaScript对象属性? –

+1

@JoshTaylor你可以在'ko.computed(fn,this,{deferEvaluation:true})'''上使用'deferEvaluation'。这对此有帮助吗? – janfoeh

2

你引用在结合这样的对象吗?

<div data-bind="text: myProperty()"></div> 

,而不是:

<div data-bind="text: myProperty"></div> 

这可能给你你正在谈论作为函数被调用的结合问题。

相关问题