简体   繁体   English

剔除绑定处理程序更新不会触发observableArray的更改

[英]knockout bind handlers update is not firing for observableArray changes

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. 我试图通过单个绑定处理程序访问多个值,以防在valuesAccessor绑定对象内部发生observableArray更改的情况下,不会触发绑定处理程序更新。

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 ): 演示:( 也在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 chosen binding isn't actually accessing the observable array, so when it mutates, knockout doesn't recall your update handler because it doesn't think anything has changed that it's using. 问题在于您chosen绑定实际上并没有访问可观察的数组,因此当它发生突变时,基因剔除不会调用您的update处理程序,因为它认为使用的任何内容都没有改变。

With this binding: 通过此绑定:

chosen: {options: Options}

You're binding an entirely new object (with an options property pointing at your Options observable array). 您正在绑定一个全新的对象(带有指向您的Options可观察数组的options属性)。 This means that when you do 这意味着当你做

var value = ko.unwrap(valueAccessor());

value now contains: {options: <observableArrayFunction>} - you need to actually access the options property on it in order for knockout to register the link: value现在包含: {options: <observableArrayFunction>} -您需要实际访问它的options属性,以便敲除功能注册链接:

ko.utils.arrayForEach(value.options(),function(binding){            

});

If you make this change, you'll see that "IT WORKS!" 如果进行此更改,您将看到"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 calling valueHasMutated . 实际上,它记录了两次,一次是因为您要更新数组,另一次是因为您调用valueHasMutated

Updated snippet (with the extra valueHasMutated removed): 更新的代码段(删除了多余的值valueHasMutated ):

 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.options(),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.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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM