0

我正在尝试通过单个绑定处理程序访问多个值,如果在 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>

演示:(也在 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>

4

1 回答 1

1

问题是您的chosen绑定实际上并没有访问可观察数组,因此当它发生变异时,knockout 不会调用您的update处理程序,因为它认为它正在使用的任何东西都没有改变。

使用此绑定:

chosen: {options: Options}

您正在绑定一个全新的对象(具有options指向您的Options可观察数组的属性)。这意味着当你做

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

value现在包含:{options: <observableArrayFunction>}-您需要实际访问其options上的属性才能敲除注册链接:

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

});

如果您进行此更改,您将看到它"IT WORKS!"现在在更新时被记录。它实际上被记录了两次,一次是因为您正在更新数组,另一次是因为您正在调用valueHasMutated.

更新的片段(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>

于 2016-04-07T10:54:54.330 回答