Knockout uses data-binds to listen to changes in an input and update an underlying model. For example, the value
binding listens to change
events and writes the new value to a data-bound observable
.
If you update a value
attribute through code, the change
event isn't triggered. You'll see the new value in the UI, but the javascript model won't be updated.
You can combat this by explicitly triggering a change. Here's an example:
- Type in the
input
: you'll see a console.log
that shows knockout gets updated
- Press the button to inject a new value: you won't see a log: knockout isn't updated
- Press the last button to trigger a
change
event. You'll notice knockout now updates the model.
Of course, you can combine the two click listeners into one function. I've separated them to get the point across.
// Hidden knockout code:
(function() {
var label = ko.observable("test");
label.subscribe(console.log.bind(console));
ko.applyBindings({ label: label });
}());
// Your code
var buttons = document.querySelectorAll("button");
var input = document.querySelector("input");
buttons[0].addEventListener("click", function() {
input.value = "generated value";
});
buttons[1].addEventListener("click", function() {
// http://stackoverflow.com/a/2856602/3297291
var evt = document.createEvent("HTMLEvents");
evt.initEvent("change", false, true);
input.dispatchEvent(evt);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<input type="text" data-bind="value: label">
<button>inject value from outside</button>
<button>let knockout know something changed</button>