选择的Knockout不会设置初始选择的选项

时间:2015-05-07 19:40:25

标签: knockout.js jquery-chosen

我无法使用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 :(得分:6)

如果selectedOptions处于多种选择模式,您还必须使chosen绑定与select一起正常工作。

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

一种解决方案是创建一个新的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

答案 1 :(得分:0)

诀窍是在绑定发生后评估所选择的东西,因为如果没有<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());