2011-11-30 73 views
6

我有一個奇怪的情況。基本上,我有兩個自定義綁定,用於將DOM元素動畫化爲新值。這些是aWidth和aRight,分別爲寬度和右值賦予動畫。爲什麼我的KnockoutJS自定義綁定被觸發?

我已經實現了綁定的是這樣的:

<div class='classname' data-bind="aRight: right, aWidth: containerWidth, style: { zIndex: zindex, left: (left() + 'px'), height: (containerHeight() + 'px') }"> 

...和自定義綁定是這樣的:

  ko.bindingHandlers.aWidth = 
      { 
       update: function (element, valueAccessor, allBindingsAccessor, context) 
       { 
        // Get the value accessor 
        var value = valueAccessor(); 

        // Get the new width and the duration of the animation 
        var newWidth = ko.utils.unwrapObservable(value); 
        var duration = 500; 

        $(element).animate({ width: newWidth }, duration, "swing"); 
       } 
      }; 

      ko.bindingHandlers.aRight = 
      { 
       update: function (element, valueAccessor, allBindingsAccessor, context) 
       { 
        // Get the value accessor 
        var value = valueAccessor(); 

        // Get the new width and the duration of the animation 
        var newRight = ko.utils.unwrapObservable(value); 
        var duration = 500; 

        $(element).animate({ right: newRight }, duration, "swing"); 

        console.log("aRight Called: newRight - " + newRight + ", duration - " + duration); 
       } 
      }; 

所以問題惡有惡報,當我們改變比其他可觀察我的兩個自定義邊界observable,例如zindex。

如果我們改變了觀察的Z-索引,該值被正確地在DOM更新,但由於某些原因,我正確地結合也被觸發!...

我沒有在任何提及它我aRight自定義綁定,所以肯定不能有依賴關係?

當我的aWidth綁定被觸發時,我的aRight綁定也會被觸發,這也有點奇怪!

有沒有人有任何想法呢?

非常感謝!

Andy。

更新

這是更新索引,當其導致我正確地定義綁定火災視圖模型的一部分(這是順便說非常psudo代碼!):

var page = function() 
    { 
     this.zindex = ko.observable(0); 
     this.right = ko.observable(0); 
     // and other observables.... 
    } 

    var viewModel = function() 
    { 
     var pages = ko.oberservableArray(); 
     // populate the pages array etc... 

     this.someMethod = function() 
     { 
      // Do some stuff... 
      this.anotherMethod(); 
      // Do some other stuff 
     } 
     .bind(this); 

     this.anotherMethod() = function 
     { 
      var pageCount = this.pages().length; 
      for (var pageNum = 0; pageNum < pageCount; pageNum++) 
      { 
       var page = this.pages()[pageNum]; 
       page.zindex(/* a different value */); // This is what causes my aRight binding to fire... 
      } 
     } 
     .bind(this); 
    } 

更新

我剛纔讀的一則訊息:http://groups.google.com/group/knockoutjs/browse_thread/thread/26a3157ae68c7aa5/44c96d1b748f63bb?lnk=gst&q=custom+binding+firing#44c96d1b748f63bb

曰:

此外,結合將再次有其更新功能運行時,將觸發以及在同一個數據綁定屬性如果 另一個結合。

這是否意味着,我所看到的是我的自定義,當其他任何綁定的數據綁定屬性觸發綁定被觸發(它只是恰巧也許這Z-索引是第一次,我看到的變化) ?這是不是有點奇怪/錯?......

更新

我有一個簡單的小提琴,我認爲幾乎概括了我的問題。它看起來像任何綁定在相同的數據綁定屬性作爲自定義綁定會導致它更新!

http://jsfiddle.net/J6EPx/2/

嗯...想我要在我的自定義手動檢查,以價值是否真正被改變或不具約束力來解決它!這是否不能擊敗綁定的實際點?

我也貼在淘汰賽論壇更精確的問題:http://groups.google.com/group/knockoutjs/browse_thread/thread/d2290d96e33f1d5a

+0

我不知道這件事情做$(元素).animate()?如果不是直接改變寬度/高度來動畫,會發生什麼? –

+0

好問題...給我一個秒... :) – Andy

+0

@Alex Key,nah,使用$(元素).css(「right」,newRight +「px」);至少沒有幫助。索引更新時仍然被觸發!還是)感謝你的建議! – Andy

回答

8

這是目前的設計。任何綁定觸發時,都會觸發數據綁定中的所有綁定。這是因爲它們都包裝在一個dependentObservable中。在某些情況下,綁定彼此之間具有依賴關係(如果更新了選項,則需要運行值以確保它仍然是有效值)。但是,在某些情況下,這確實會造成問題。

創建自定義綁定有助於減輕此行爲時可以使用的不同模式。您不必在「更新」功能中定義您的功能,您實際上可以在「init」函數中創建自己的dependentObservable。它看起來像:

ko.bindingHandlers.custBinding= { 
    init: function(element, valueAccessor) { 
     ko.dependentObservable({ 
      read: function() { 
       ko.utils.unwrapObservable(valueAccessor()); 
       alert("custBinding triggered"); 
      }, 
      disposeWhenNodeIsRemoved: element 
     }); 
    } 
}; 

http://jsfiddle.net/rniemeyer/uKUfy/

+1

花了一點時間,讓我的腦袋周圍,但你的建議聽起來很合理!我必須承認,我有點驚訝,默認是將它們全部包裝在一個dependentObservable中。我不認爲WPF/Silverlight以這種方式工作...不要說這是錯的...只是混淆! :) – Andy

+0

默認行爲在許多情況下並不理想,可能/應該改進。我們將不得不平衡這與打破現有行爲(一些人目前使用自定義綁定,不訪問observables,並依靠其他綁定被觸發)。 –

+0

非常真實! 「這是一個棘手的情況! – Andy

相關問題