我正在使用淘汰赛选择绑定,其中将整个对象绑定为值......而不仅仅是一个字符串。
bootstrap-multiselect 不喜欢这样,因为它使用“值”将其下拉列表项关联回相应的选择选项。 为了做到这一点,您必须在淘汰赛绑定中设置“optionsValue”属性,以便该选项具有“value”属性。 但是,设置“optionsValue”属性然后具有仅在我的 selectedOptions observableArray 中设置该值的预期结果......而不是整个对象。
很有可能我是唯一一个在淘汰赛中使用功能的人,该功能可让您将选项绑定到整个对象,但以防万一我不是......这是黑客修复:
创建了两个新的 bootstrap-multiselect 选项,称为“optionsKey”和“observableKey”,以便它知道去哪里寻找与它相关的值:
<select id="mySelect" data-bind="options: myOptions, selectedOptions: mySelectedOptions, optionsText: 'myDisplayText', optionsAfterRender: SetOptionKey, multiselect: { optionsKey: 'data-key', observableKey: 'Key' }" multiple="multiple"></select>
在我的淘汰赛视图模型中,我在每个选项上设置了“optionsKey”引用的属性:
myVM.SetOptionKey = function ( option, item ) {
ko.applyBindingsToNode( option, { attr: { "data-key": item.Key } }, item );
};
现在我深入研究 bootstrap-multiselect.js 文件。 我必须在这里做的第一件事是在顶部添加淘汰赛 init 处理程序。
init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
...
if (allBindings.has('selectedOptions')) {
var selectedOptions = allBindings.get('selectedOptions');
if (ko.isObservable(selectedOptions)) {
ko.computed({
read: function () {
selectedOptions();
// Added to handle knockout binding to an object...not just a value
// multiselect needs the selected property on the options, else it wont show them on refresh
if ((config.optionsKey !== undefined) &&
(config.optionsKey !== null) &&
(config.optionsKey.length > 0) &&
(config.observableKey !== undefined) &&
(config.observableKey !== null) &&
(config.observableKey.length > 0)) {
var _optionsKey = config.optionsKey;
var _observableKey = config.observableKey;
ko.utils.arrayForEach(selectedOptions(), function (selectedOption) {
$("option[" + _optionsKey + "='" + selectedOption[_observableKey]() + "']", $element).prop('selected', true);
})
}
setTimeout(function () {
$element.multiselect('refresh');
}, 1);
},
disposeWhenNodeIsRemoved: element
}).extend({ rateLimit: 100, notifyWhenChangesStop: true });
}
}
...
接下来,我必须修改 bootstrap-multiselect.js 中的 createOptionValue 函数,以首先使用此键作为它在其列表项中设置的值:
createOptionValue: function (element) {
...
var value = $element.val();
// Added to handle knockout binding to an object...not just a value
if ((this.options.optionsKey !== undefined) && (this.options.optionsKey !== null) && (this.options.optionsKey.length > 0)) {
var key = $element.attr(this.options.optionsKey);
if ((key !== undefined) && (key !== null) && (key.length > 0)) {
value = key;
}
}
...
}
最后,我不得不修改 bootstrap-multiselect.js 中的 getOptionByValue 函数,以根据此属性而不是值查找选项元素:
getOptionByValue: function (value) {
var valueToCompare = value.toString();
// Added to handle knockout binding to an object...not just a value
if ((this.options.optionsKey !== undefined) && (this.options.optionsKey !== null) && (this.options.optionsKey.length > 0)) {
var opt = $("option[" + this.options.optionsKey + "='" + valueToCompare + "']", this.$select).first();
if( (opt !== undefined) && (opt !== null) ) {
return $(opt);
}
}
var options = $('option', this.$select);
for (var i = 0; i < options.length; i = i + 1) {
var option = options[i];
if (option.value === valueToCompare) {
return $(option);
}
}
},
谢谢,将在常见问题解答中包含此内容! 我相信这对其他用户也有帮助。
谢谢你的提示 - 我也试图完成对选择对象的绑定,这篇文章非常有帮助。 除了@APM3的代码之外,我唯一要做的就是在 SetOptionKey 函数中填充我的选项的“value”属性:
self.SetOptionKey = function (option, item) {
ko.applyBindingsToNode(option, { attr: { "data-key": item.Value } }, item);
ko.applyBindingsToNode(option, { attr: { "value": item.Value } }, item);
}
再次感谢您写这篇文章。