2011-11-30 8 views
6

Tuhaf bir durum var. Temel olarak, DOM öğesinin yeni değerine animasyon uygulamak için kullanılan iki özel bağlarım var. Bunlar sırasıyla genişlik ve doğru değerleri canlandıran aWidth ve aRight'dır.KnockoutJS özel bağlarım neden tetikleniyor?

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

... ve özel bağlamaları şuna benzer:

böyle bağlamaları uyguladık biz daha gözlemlenebilir bir başka değiştirdiğinizde

  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); 
       } 
      }; 

Yani sorun etrafında geliyor iki özel gözlemlenebilir gözlemcim, örneğin zindex. Biz gözlemlenebilir zIndex değiştirirseniz

, değer DOM doğru güncellenir, ama nedense benim aright da tetiklendiğinde bağlanma! ...

ben gönderiminden yok benim aYüksek özel bağlama var, bu yüzden kesinlikle bir bağımlılık olamaz?

Ayrıca aWidth bağlanma da tetiklendiğinde aRight bağlanma da tetikleniyor, bu da biraz garip!

Bu konuda herhangi bir fikri olan var mı?

Çok teşekkürler!

Andy.

Bu yangına bağlayıcı benim aright özel nedenleri indeksi, günceller görünümü modelinin bir parçası olan

Güncelleme (bu arada çok psudo-kodu!):

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); 
    } 

Güncelleme

burada sadece bir yazı okumak

: http://groups.google.com/group/knockoutjs/browse_thread/thread/26a3157ae68c7aa5/44c96d1b748f63bb?lnk=gst&q=custom+binding+firing#44c96d1b748f63bb

deyiş: Ayrıca

, bir eğer başka yanı tetiklenir aynı veri-bağlama özelliğinde bağlayıcı, yine güncelleme fonksiyonu çalıştırmak zorunda kalacak bağlayıcı.

bu nedir görüyorum başka veri bağlama özniteliği tetiklenir bağlanma benim özel tetiklediği bağlanmanın olduğu anlamına mı geliyor (sadece çok o zIndex ben değişim görüyoruz ilk belki olur) ? Mı bu değil biraz yanlış/garip? ...

Ben hemen hemen özetliyor benim sorunum düşünüyorum basit bir keman var

Güncelleme. Özel bağlamanın güncellenmesine neden olacağından, aynı veri bağlama özniteliğinde herhangi bir bağlanma gibi görünüyor!

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

Hmmm ... Ben elle değeri aslında değişip değişmediğini ya da olmamak gibi bağlanma benim özel kontrol ederek etrafında çalışmak zorunda kalacağım !!Bu bir bağlanma gerçek noktasını yenilemez mi ??? http://groups.google.com/group/knockoutjs/browse_thread/thread/d2290d96e33f1d5a

+0

: gibi görünürdü? Animasyon yapmak yerine sadece genişliği/yüksekliği doğrudan değiştirirseniz ne olur? –

+0

İyi soru ... bana bir saniye verin ... :) – Andy

+0

@Alex Key, nah, $ (element) .css ("right", newRight + "px") kullanarak; en azından yardım etmedi. İndeks güncellendiğinde hala tetikleniyor! Öneri için teşekkürler! – Andy

cevap

8

Bu, tasarımdan şu anda:

Ben de Nakavt forumlarında daha kesin soru gönderdiniz. Veri bağlamasındaki tüm bağlamalar, bağlantılardan herhangi biri tetiklendiğinde tetiklenir. Bunun nedeni, hepsi tek bir bağımlılığa karşı korumalı olmalarıdır. Bazı durumlarda, bağlamalar birbirinin arasında bir bağımlılığa sahiptir (seçenekler güncellenirse, değer hala geçerli bir değer olduğundan emin olmak için çalışmalıdır). Ancak, bazı durumlarda, bu bir soruna neden olur.

Bu davranışı azaltmaya yardımcı olan özel bir bağ oluştururken kullanabileceğiniz farklı bir desen var. "Güncelleme" işlevindeki işlevsellikinizin bağırsaklarını tanımlamak yerine, aslında "init" işlevinde kendi bağımlılığınızı koruyabilirsiniz. Ben $ (eleman) .animate ile ilgili bir şey() olmadığını merak

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

Kafamı biraz döndürmek için biraz zaman aldı, ama öneriniz mantıklı geliyor! Yine de itiraf etmeliyim ki, varsayılanın hepsinin tek bir bağımlılığı olan bir kutuda sarmak olduğuna biraz şaşırdım. WPF/Silverlight'ın bu şekilde çalıştığını sanmıyorum ... yanlış olduğunu söylememek ... sadece kafa karıştırıcı! :) – Andy

+0

Varsayılan davranış çoğu durumda ideal değildir ve geliştirilebilir/geliştirilmelidir. Sadece mevcut davranışı kırmakla dengelemeliyiz (bazı insanlar şu anda gözlenebilirlere erişmeyen ve tetiklenen diğer bağlayıcılara dayanan özel bağlamalar kullanmaktadır). –

+0

Çok doğru! Bu zor bir durum! – Andy