I am trying to access multiple values through single bind handler, in case of observableArray changes which is inside the valuesAccessor binding object, the bind handler update is not firing.
ko.bindingHandlers.chosen = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
console.log("INIT");
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
var value = ko.unwrap(valueAccessor());
ko.utils.arrayForEach(value,function(binding){
var value = ko.unwrap(binding);
});
console.log("IT WORKS!");
}
};
<select data-bind="
options: Options,
chosen: {options: Options}
"></select>
Demo: (also on jsFiddle):
ko.bindingHandlers.chosen = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
console.log("INIT");
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
var value = ko.unwrap(valueAccessor());
ko.utils.arrayForEach(value,function(binding){
var value = ko.unwrap(binding);
});
console.log("IT WORKS!");
}
};
function Model() {
this.Options = ko.observableArray(opt1);
this.Reload = function () {
if (!this.index) {
this.Options(opt2);
this.index = 1;
} else {
this.Options(opt1);
this.index = 0;
}
this.Options.valueHasMutated();
};
this.index = 0;
}
var opt1 = [{
Text: "1",
Value: "1"
}, {
Text: "2",
Value: "2"
}, ];
var opt2 = [{
Text: "3",
Value: "3"
}, {
Text: "4",
Value: "4"
}, ];
ko.applyBindings(new Model());
<select data-bind="
options: Options,
value: Selection,
optionsText: 'Text',
optionsValue: 'Value',
chosen: {options: Options}
"></select>
<input type="button" data-bind="click: Reload" value="reload" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
The problem is that your
chosenbinding isn't actually accessing the observable array, so when it mutates, knockout doesn't recall yourupdatehandler because it doesn't think anything has changed that it's using.With this binding:
You're binding an entirely new object (with an
optionsproperty pointing at yourOptionsobservable array). This means that when you dovaluenow contains:{options: <observableArrayFunction>}- you need to actually access theoptionsproperty on it in order for knockout to register the link:If you make this change, you'll see that
"IT WORKS!"is now logged when it updates. It actually gets logged twice, once because you're updating the array, and another because you're callingvalueHasMutated.Updated snippet (with the extra
valueHasMutatedremoved):