knockout.js input box event change - passes old va

2019-03-10 17:01发布

问题:

When adding a change event binding to an input box using knockout.js the old value is passed to the change function when the event is fired. I can work around this by using blur. Is this the intended behavior? Is the idea to use the change event to have the old value and then use a normal selector to get the value from the dom? It seems counter intuitive.

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>

回答1:

Try using the text and value bindings:

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

And change the JavaScript to this:

var data = {
    saved_value: "1"    
};

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

Here's an associated jsFiddle: http://jsfiddle.net/6zmJs/

If you want to alert() the value of saved_value when it is updated you could use ko.computed or viewModel.saved_value.subscribe(function(value) { alert(value); }); -- although those aren't the only ways to do this.



回答2:

Update: For newer versions of knockout, you can replace the value binding with textInput, which handles many edge cases not covered by valueUpdate.


No, this is not the right way to do things.

You're getting the old value because saved_value doesn't get updated until the textbox loses focus.

If you want to push the new value in as the user types, using the valueUpdate option of the input binding:

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

The valueUpdate option takes an event name (e.g. 'keyup'). When that event fires, your saved_value will be updated.


Now let me propose an alternate solution.

Still do the valueUpdate binding like I showed above, but instead of listening for the changed event, just subscribe to the observable:

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

Then in JS:

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


回答3:

If you put the 'event' option at the end you don't need the 'valueUpdate' option. Like this:

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

Also note that when you make use of subscribe to an observable, it gets triggered every time your value changes. (either by user interaction or programmatically).



回答4:

Try this in the data bind write event handlers, after the value handlers and not before:

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