2013-09-16 33 views
3

的「樹」我有一個具有多個可觀測性挖空模型:創建淘汰賽結合處理程序取決於觀測

var personViewModel = { 
    name: ko.observable('Bob'), 
    age: ko.observable(123) 
}; 

我想創建一個自定義綁定這使得人稱視角模式。不過,如果更新任何子屬性,即nameage,我希望更新此綁定。

使用bindingHandler時,更新方法僅在綁定的observable屬性更新時觸發,而不是綁定的observables上的子屬性更改時觸發。

作爲一種變通方法,我在init功能附加訂閱子屬性:

ko.bindingHandlers.foo = { 
    init: function (element, valueAccessor, allBindingsAccessor, 
        viewModel, bindingContext) { 
     // setup code goes here ... DOM elements inserted etc.... 

     valueAccessor().age.subscribe(function() { 
      // Update the UI 
     }); 
     valueAccessor().name.subscribe(function() { 
      // Update the UI 
     }); 
    }, 
    update: function (element, valueAccessor, allBindingsAccessor, 
         viewModel, bindingContext) { 
     // Update the UI 
    } 
}; 

注:這是一個簡單的例子,我有用於訂閱多個子觀測一個通用的方法!

這是解決問題的好方法嗎?還是有一些內置的Knockout功能,我可以在這裏忽略它?

回答

4

ko.toJS將聯播的依賴關係,因此,如果你把這個在你的更新將解決所有依賴你

http://jsfiddle.net/rMG8y/

ko.bindingHandlers.foo = { 
    update: function(element, valueAccessor) { 
     //Resolve dependency 
     var dependency = ko.toJS(valueAccessor()); 

     //Do whatever 
     console.log(dependency); 
    } 
}; 
+0

這實際上很聰明... –

+1

真棒 - 這工作(+1),但...它是如何工作的?我明白'toJS'的作用,但不是爲什麼這會導致綁定在任何值更改時更新? – ColinE

+1

好吧,它迭代對象樹並展開可觀察對象,這將解決依賴關係 – Anders

0

除了之前已經提到的,我發現下面的文章對理解很有幫助綁定處理程序如何與淘汰賽工作的依賴性:

http://www.knockmeout.net/2012/06/knockoutjs-performance-gotcha-3-all-bindings.html

簡而言之,給定元素的所有綁定處理程序都在單個計算的observable的上下文中運行(文章中有一個註釋可能會更改,以便每個綁定處理程序都在它自己的計算observable的上下文中運行 - 此發生在3.0)。每次計算observable中的函數時,都會重新創建Knockout依賴關係,這就是爲什麼每次都必須在更新中解包observable時纔會失去依賴關係,因爲如果只是在init中展開observable的話,就會出現這種情況。

在這篇文章中,他提出了一個選項,你的綁定處理程序,以配合您希望將一些功能的任何可觀察量初始化創建一個計算觀察到:

 var args = arguments; 
     ko.computed(function() 
     { 
      ko.utils.unwrapObservable(valueAccessor()/*or whatever observable you want to tie the update to*/); 
      doUpdateLogic(/*args or whatever you need*/); 
     }, this); 

這顯然是危險的,所以請謹慎使用:)