2012-03-03 12 views
28

Al agregar un enlace de evento de cambio a un cuadro de entrada usando knockout.js, el valor anterior pasa a la función de cambio cuando se dispara el evento. Puedo solucionar esto usando blur. ¿Es este el comportamiento previsto? ¿La idea de usar el evento de cambio tiene el valor anterior y luego usar un selector normal para obtener el valor del dom? Parece contra intuitivo.knockout.js cambio de evento de cuadro de entrada - pasa el valor anterior

jsFiddle Example

JavaScript 
---------- 
var data = { 
    saved_value:"1", 
    value_changed: function(data){ 
     alert(data.saved_value()); 
    } 
}; 
var viewModel = ko.mapping.fromJS(data); 
ko.applyBindings(viewModel); 

HTML 
---- 
Current Value:<span data-bind="text:saved_value"></span><br/> 
<input data-bind="event:{change:value_changed},value:saved_value"></input> 

Respuesta

6

Intente utilizar los enlaces de texto y de valor:

Current Value:<span data-bind="text: saved_value"></span><br/> 
<input data-bind="value: saved_value"></input> 

y cambiar el Javascri pt a esto:

var data = { 
    saved_value: "1"  
}; 

var viewModel = ko.mapping.fromJS(data); 
ko.applyBindings(viewModel);​ 

He aquí un jsFiddle asociado: http://jsfiddle.net/6zmJs/

Si desea alert() el valor de saved_value cuando se actualiza podría utilizar ko.computed o viewModel.saved_value.subscribe(function(value) { alert(value); }); - aunque esas no son las únicas maneras para hacer esto.

+0

saved_value debería ser ko.observable ("1") –

68

No, esto no es la forma correcta de hacer las cosas.

Obtiene el valor anterior porque saved_value no se actualiza hasta que el cuadro de texto pierde el foco.

Si usted quiere empujar el nuevo valor en la medida que el usuario, mediante la opción valueUpdate de la unión de entrada:

<input data-bind="event: { change: value_changed }, value: saved_value, valueUpdate: 'afterkeydown'" /> 

La opción valueUpdate toma un nombre de evento (por ejemplo, 'keyup'). Cuando se desencadena ese evento, su valor_guardado se actualizará.


Ahora permítanme proponer una solución alternativa.

todavía lo hacen el valueUpdate vinculante como he mostrado antes, pero en vez de detectar el evento cambiado, simplemente suscribirse a lo observable:

<input data-bind="textInput: saved_value" /> 

Luego, en JS:

var viewModel = { 
    saved_value: ko.observable("1"), 
}; 
viewModel.saved_value.subscribe(function (newValue) { 
    alert(data.saved_value()); 
}); 
ko.applyBindings(viewModel); 
+2

tengo que usar 'afterkeydown', por lo demás estoy un carácter tarde. –

+0

Buen punto, actualizaré la respuesta. –

+0

¿Hay alguna razón por la cual no se utiliza el 'textInput binding'? La documentación de KO recomienda utilizar 'textInput binding' en lugar de' value binding': http://knockoutjs.com/documentation/textinput-binding.html "Aunque el enlace de valores también puede funcionar en dos sentidos vinculando entre cuadros de texto y propiedades del modelo de vista, debe preferir la entrada de texto cada vez que desee actualizaciones inmediatas en vivo ". –

10

Si coloca la opción 'evento' al final no necesita la opción 'valueUpdate'. De esta manera:

<input data-bind="value: saved_value, event: { change: value_changed }" />

También tenga en cuenta que al hacer uso de suscribirse a un observable, que se dispara cada vez que cambie su valor. (ya sea por interacción del usuario o por programación).

+1

Entonces, ¿el orden en que los artículos están en "data-bind" tiene relevancia? ¿Existe algún documento que explique qué reglas se deben seguir para evitar futuros problemas? – Ominus

+1

Sí, el orden es importante, suceden en orden de izquierda a derecha (dependiendo de su funcionalidad) – pilavdzice

+0

Solo lanzando esto, pero si está utilizando el enlace "marcado", usar evento al final * no * hazlo esperar hasta que los datos hayan cambiado. Todavía usará el valor anterior. – Andrew

3

Prueba esto en los controladores de eventos de escritura enlazar datos, después de que los manejadores de valor y no antes:

<input data-bind="value: property, event:{ change: doSomething}" /> 
+0

Este fue exactamente mi problema. ¡Gracias! –

Cuestiones relacionadas