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>
In the root context, $data and $root are equivalent. Inside a nested binding context, this parameter will be set to the current data item (e.g., inside a with: person binding, $data will be set to person ). $ data is useful when you want to reference the viewmodel itself, rather than a property on the viewmodel.
To create an observable, assign the ko. observable function to the variable. A default value can be specified in the constructor of the call. Knockout then converts your variable into a function and tracks when the value changes, in order to notify the UI elements associated with the variable.
KO is able to create a two-way binding if you use value to link a form element to an Observable property, so that the changes between them are exchanged among them. If you refer a simple property on ViewModel, KO will set the form element's initial state to property value.
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);
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With