首页 文章

选择的Knockout没有设置初始选择的选项

提问于
浏览
4

我在使用Chosen和Knockout 3.3.0设置最初选择的选项时遇到问题 .

我已经实现了this question的自定义选择绑定,它非常适合选择元素:

ko.bindingHandlers.chosen = {
    init: function (element) {
        ko.bindingHandlers.options.init(element);
        $(element).chosen({ disable_search_threshold: 10 });
    },
    update: function (element, valueAccessor, allBindings) {
        ko.bindingHandlers.options.update(element, valueAccessor, allBindings);
        $(element).trigger('chosen:updated');
    }
};

问题是,如果我设置了初始值,它将不会显示为选中:

<select multiple class="chosen-select" data-bind="chosen: options,
                                        optionsText: 'Label',
                                        optionsValue: 'Id',
                                        selectedOptions: selected">
</select>

如果我使用常规选项绑定,它可以正常工作:

<select multiple data-bind="options: options,
                                        optionsText: 'Label',
                                        optionsValue: 'Id',
                                        selectedOptions: selected">
</select>

我已将两者都实现为jsFiddle . 如果更改 self.selected observableArray(),然后运行,您可以看到它反映在第二个 <select> 中,但第一个没有显示 .

2 回答

  • 0

    如果 select 处于多选模式,您还必须使 selectedOptions 绑定与 chosen 正确配合 .

    问题是,当 selected 可观察数组更改 selectedOptions 时,正确设置DOM中的选定选项但不会触发 'chosen:updated' 事件,因此不会更新 chosen multiselect .

    一种解决方案是创建一个新的 chosenSelectedOptions ,它委托给原始处理程序并触发 update 中的事件:

    ko.bindingHandlers.chosenSelectedOptions = {
                init: function (element, valueAccessor) {
                    ko.bindingHandlers.selectedOptions.init(element, valueAccessor);
                },
                update: function (element, valueAccessor, allBindings) {
                    ko.bindingHandlers.selectedOptions.update(element, valueAccessor, allBindings);
                    $(element).trigger('chosen:updated');
                }
            };
    

    并在绑定中使用它:

    <select multiple class="chosen-select" data-bind="chosen: options,
                                                optionsText: 'Label',
                                                optionsValue: 'Id',
                                                chosenSelectedOptions: selected"></select>
    

    演示JSFiddle .

  • 6

    诀窍是在绑定发生后评估所选择的东西,因为如果没有 <options> 在DOM中,所选择的东西将无法正确初始化 .

    使用setTimeout这有点难看,但它可以工作,因为它会延迟重新初始化,直到绑定完成 .

    编辑:使用订阅处理所选选项的更改 . 我觉得这比接受的答案更加独立 .

    ** FIDDLE:**

    https://jsfiddle.net/brettwgreen/xp1b7cff/

    JS:

    ko.bindingHandlers.chosen = {
        init: function (element, valueAccessor, allBindings) {
            ko.bindingHandlers.options.init(element, valueAccessor, allBindings);
            var options = ko.unwrap(valueAccessor);
            var el = $(element);
            el.chosen();
            var selectedOptions = allBindings.get('selectedOptions');
            if (ko.isObservable(selectedOptions)) {
                selectedOptions.subscribe(function () {
                    setTimeout(function () {
                        el.trigger('chosen:updated');
                    }, 10);
                }, null, 'change');
            }
        },
        update: function (element, valueAccessor, allBindings) {
            ko.bindingHandlers.options.update(element, valueAccessor, allBindings);
        }
    };
    
        function viewModel() {
    
            var self = this;
    
            self.options = ko.observableArray([{ Id: 1, Label: 'Administrator' }, { Id: 2, Label: 'Moderator' }]);
    
            self.selected = ko.observableArray([2]);
    
        }
        ko.applyBindings(new viewModel());
    

相关问题