Knockout with Chosen 不设置初始选择的选项
Knockout with Chosen doesn't set the initial selected options
我在使用 Chosen 和 Knockout 3.3.0 设置最初选择的选项时遇到问题。
我已经实现了来自 this question 的自定义 Chosen 绑定,它非常适合选择元素:
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>
中,但在第一个中什么也没有显示。
诀窍是在绑定发生后评估所选内容,因为如果 <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());
如果 select
处于多选模式,您还必须设置 selectedOptions
绑定才能与 chosen
一起正常工作。
问题是,当您的 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.
我在使用 Chosen 和 Knockout 3.3.0 设置最初选择的选项时遇到问题。
我已经实现了来自 this question 的自定义 Chosen 绑定,它非常适合选择元素:
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>
中,但在第一个中什么也没有显示。
诀窍是在绑定发生后评估所选内容,因为如果 <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());
如果 select
处于多选模式,您还必须设置 selectedOptions
绑定才能与 chosen
一起正常工作。
问题是,当您的 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.