2012-09-01 11 views
15

I tienen un elemento de entrada que está unido a un nocaut observable:Knockout.JS: activadores basados ​​en los cambios en un observable

<input type="text" data-bind="value: myText, valueUpdate: 'keyup'" /> 

Esto actualiza el observable en cada keyup. Ahora quiero activar eventos adicionales cuando el valor cambie.

A continuación se hace esto, en principio:

this.myTextTrigger = ko.computed(function() { 
    console.log(this.myText()); 
}, this); 

Sin embargo, parece un poco torpe. También se desencadena en la creación de instancias inicial de la plantilla, donde solo quiero gestionar los cambios posteriores. ¿Existe alguna manera oficial/más sencilla de activar eventos en función de los cambios observables?

Respuesta

31

uso suscribirse:

this.myText.subscribe(function (newText) { 
    console.log(newText); 
}); 

Si desea volver a utilizar este disparador se puede considerar escribiendo un custom binding.

+2

+1 para suscripciones manuales (http://knockoutjs.com/documentation/observables.html#explicitly_subscribing_to_observables) –

+0

Un enlace personalizado parece exagerado para una sola entrada en mi humilde opinión. Una suscripción me parece una mejor opción. –

+0

Justo lo que estaba buscando. ¡Gracias! - Con respecto a los enlaces personalizados: ¿Existe alguna forma de tener un enlace generalizado para los campos donde se supone que los cambios deben desencadenar otros eventos, y pasar esta función a la ejecución desde el enlace en el HTML? – gzost

3

Si usted está tratando de obtener información adicional en su unión a continuación, utilizar allBindings.get(nameOfOtherBinding) y establecer el parámetro nameOfOtherBinding para hacer referencia al nombre de la unión en el elemento que está apuntando a una función. Ponga la función literal en el HTML o asegúrese de que puede encontrar esa función en el alcance de la definición de manejadores (como globalmente adjunta al objeto window).

http://knockoutjs.com/documentation/custom-bindings.html

JS Fiddle Example - http://jsfiddle.net/pqb4xubg/

El javascript que configurar el controlador (ya sea en init o actualización):

ko.bindingHandlers.generic = { 
    init: function(element, valueAccessor, allBindings){ 
     var val = 'nothing'; 
     // set your other bindings to get pulled in 
     var func = allBindings.get('func'); 
     // normal check if the binding is actually a function 
     if(typeof func === 'function'){ 
      // use the retrieved function 
      val = func(valueAccessor()); 
     } 
     element.innerText = val; 
    } 
}; 
var model = {a:'4', b:5}; 
ko.applyBindings(model); 

el código HTML que se utilice el controlador (aviso cómo los elementos con el enlace "divertido" no funcionan):

<div data-bind="generic: a, func: function(val){ return val + 2; }"></div> 
<div data-bind="generic: a, fun: function(val){ return val + 2; }"></div> 
<div data-bind="text: a"></div> 
<div data-bind="generic: b, func: function(val){ return val + 2; }"></div> 
<div data-bind="generic: b, fun: function(val){ return val + 2; }"></div> 
<div data-bind="text: b"></div> 

También puede simplemente usar el init del enlace para configurar manejadores de eventos DOM estándar y simplemente llamar explícitamente esas funciones usando algo como jQuery. Gracias. Buen día.

Cuestiones relacionadas