2011-11-30 20 views
6

Tengo una situación extraña. Básicamente, tengo dos enlaces personalizados que se utilizan para animar el elemento DOM a su nuevo valor. Estos son aWidth y aRight, que animan los valores de ancho y derecho, respectivamente.¿Por qué se activa mi encuadernación personalizada KnockoutJS?

he implementado las fijaciones de la siguiente manera:

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

... y los enlaces personalizados tener este aspecto:

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

Así que el problema viene por ahí cuando cambiamos de otro observable mis dos observables enlazados personalizados, por ejemplo zindex.

Si cambiamos el zindex observable, el valor se actualiza correctamente en el DOM, pero por alguna razón, mi unión correctamente también se desencadena! ...

no tengo ninguna referencia a ella en mi aEncuadernación personalizada correcta por lo que seguramente no puede haber una dependencia?

Mi aRight binding también se activa cuando se activa mi enlace de ancho, lo que también es un poco extraño.

¿Alguien tiene alguna idea al respecto?

¡Muchas gracias!

Andy.

actualización

Esta es la parte del modelo de vista que se actualiza el índice, que cuando se hace que mi unión a aduana fuego correctamente (esto es mucho psudo de código por cierto!):

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

actualización

acabo de leer un post aquí: http://groups.google.com/group/knockoutjs/browse_thread/thread/26a3157ae68c7aa5/44c96d1b748f63bb?lnk=gst&q=custom+binding+firing#44c96d1b748f63bb

dicho:

Además, una unión tendrá su función de ejecución de actualización de nuevo, si otra unión en el mismo atributo de enlazar datos se activa también.

¿Esto significa que lo que estoy viendo es que mi costumbre unión se activa cuando cualquier otra unión en los datos-bind se activa el atributo (Lo que pasa es que tal vez zindex es la primera que veo modificar) ? ¿No es esto un poco extraño/mal? ...

actualización

Tengo un violín simple que creo que resume bastante bien mi problema. Parece que cualquier enlace en el mismo atributo de enlace de datos, ¡tanto enlace personalizado hará que se actualice!

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

Hmmm ... que voy a tener que trabajar alrededor de ella mediante la comprobación manual en mi costumbre vinculante en cuanto a si el valor ha cambiado realmente o no !!¿Esto no derrota ese punto real de un enlace?

también he publicado una pregunta más precisa en los foros Knockout: http://groups.google.com/group/knockoutjs/browse_thread/thread/d2290d96e33f1d5a

+0

Me pregunto si es algo que ver con .animate (elemento) $()? ¿Qué sucede si en vez de animar simplemente cambia el ancho/alto directamente? –

+0

Buena pregunta ... dame un segundo ... :) – Andy

+0

@Alex Key, nah, usando $ (elemento) .css ("derecha", nuevoRecto + "px"); no ayudó al menos. ¡Todavía se activa cuando se actualiza el índice! ¡Gracias por la sugerencia! – Andy

Respuesta

8

Ésta es actualmente por diseño. Todas las vinculaciones en un enlace de datos se desencadenan cuando se activa cualquiera de los enlaces. Esto se debe a que están todos envueltos en un solo dependienteObservable. En algunos casos, los enlaces tienen una dependencia entre ellos (si las opciones se actualizan, entonces el valor debe ejecutarse para garantizar que siga siendo un valor válido). Sin embargo, en algunos casos, esto causa un problema.

Hay un patrón diferente que puede usar al crear un enlace personalizado que ayuda a mitigar este comportamiento. En lugar de definir las agallas de su funcionalidad en la función "actualizar", realmente crearía su propio dependiente observable en la función "init". Que se vería así:

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

Tomo un poco de tiempo para entender esto, ¡pero su sugerencia parece sensata! Debo admitir, sin embargo, que estoy un poco sorprendido de que el valor predeterminado sea envolverlos todos en un solo dependienteObservable. No creo que WPF/Silverlight funcione de esta manera ... por no decir que está mal ... ¡simplemente confuso! :) – Andy

+0

El comportamiento predeterminado no es ideal en muchos casos y podría/debería mejorarse. Tendremos que equilibrar eso con romper el comportamiento existente (algunas personas actualmente usan enlaces personalizados que no acceden a los observables y dependen de que se desencadenen otras vinculaciones). –

+0

¡Muy cierto! ¡Es una situación difícil! – Andy

Cuestiones relacionadas