2012-03-08 5 views
106

He escrito algunos enlaces personalizados usando KnockoutJS. Todavía no estoy seguro de cuándo usar ko.util.unwrapObservable(item) Mirando el código, esa llamada básicamente verifica si item es observable. Si lo es, devuelve el valor(), si no es así, solo devuelve el valor. En cuanto a la sección sobre el golpe de gracia sobre la creación de enlaces personalizados, tienen la siguiente sintaxis:Cuándo usar ko.utils.unwrapObservable?

var value = valueAccessor(), allBindings = allBindingsAccessor(); 
var valueUnwrapped = ko.utils.unwrapObservable(value); 

En este caso, se puede observar a través de invocar la () pero entonces también llamar ko.utils.unwrapObservable. Solo trato de entender cuándo usar uno frente a otro o si siempre debo seguir el patrón anterior y usar ambos.

Respuesta

135

Debe utilizar ko.utils.unwrapObservable en los casos en que no sabe si se le ha dado un observable o no. Esto comúnmente sería en un enlace personalizado donde un observable o no observable podría estar ligado a él.

En el código que tienes arriba, la llamada a valueAccessor() no está realmente desenvuelto. Simplemente recupera el valor que se pasó al enlace en el contexto correcto (se envuelve en una función para protegerlo). El valor de retorno de valueAccessor() puede ser observable o no. Es lo que pasó con la encuadernación.

+0

Entonces, ¿el patrón que he publicado es la mejor práctica para las encuadernaciones personalizadas en el futuro? – arb

+4

Realmente depende de la situación. Algunos enlaces personalizados están diseñados para funcionar únicamente con observables, por lo que puede verificar desde el principio (ko.isObservable) que es un observable y entonces sería libre de desenvolverlo con(). Si está recibiendo un objeto que puede tener observables anidados, entonces es mejor que haga un 'ko.toJS (suObjeto)' en lugar de utilizar 'ko.utils.unwrapObservable', si está tratando de obtener una versión desenvuelta del objeto pasar a un widget o a una biblioteca de terceros. En general, es más seguro usar 'ko.utils.unwrapObservable' para admitir observables y no observables. –

+2

Supongo que estoy confundido con el propósito de 'ko.utils.unwrapObservable'. Al mirar el código, simplemente verifica si es observable y si lo es, Knockout invoca '()' para obtener el valor de lo observable, de lo contrario, simplemente devuelve el valor de no observable. Si todo lo que me interesa es el valor de los datos pasados ​​al enlace, ¿por qué no puedo usar siempre '()'? – arb

9

La respuesta anterior es correcta, pero a menudo paso funciones a los enlaces personalizados (una función que comprueba los permisos, o determina qué hacer en función de otra cosa, etc.). Lo que realmente necesitaba era desenvolver cualquier función, incluso si no es observable.

La siguiente desenvuelve de forma recursiva todo:

ko.utils.unwrapFunction = function (func) { 
    if (typeof func != 'function') { 
     return func; 
    } 
    else { 
     return ko.utils.unwrapFunction(func()); 
    } 
}; 

Este es un ejemplo de una simple unión a medida que escribí:

//replaces single and double 'smart' quotes users commonly paste in from word into textareas and textboxes with normal text equivalents 
//USAGE: 
//data-bind="replaceWordChars:true 
//also works with valueUpdate:'keyup' if you want" 

ko.bindingHandlers.replaceWordChars = { 
    update: function (element, valueAccessor, allBindingsAccessor, viewModel) { 
     var bindingValue = ko.utils.unwrapFunction(valueAccessor); 

     if (bindingValue) { 
      $(element).val(removeMSWordChars(allBindingsAccessor().value())); //update DOM - not sure why I should need to do this, but just updating viewModel doesn't always update DOM correctly for me 
      allBindingsAccessor().value($(element).val()); //update viewModel 
     } 
    } 
} 

De esta manera bindingValue siempre contiene un valor. No necesito preocuparme si paso en una función, un observable, un valor o incluso una función dentro de un observable. Esto desenvolverá adecuadamente todo hasta que llegue al objeto que quiero.

Espero que ayude a alguien.

+9

No estoy sobreescribiendo nada, unwrapObservable todavía está allí, el mío se llama unfrapFunction. ko.utils es un espacio de nombres lógico para que esto esté puesto ya que es una función de utilidad de eliminación directa. Estoy de acuerdo que es un poco complicado pero decidí poner esto en ese espacio de nombres por la misma razón que el plugin de mapeo se pone en el espacio de nombres ko aunque no viene con ko, tener un espacio de nombres completamente nuevo solo para esto no parece que valga la pena. – pilavdzice

Cuestiones relacionadas