编辑替代解决方案见下文
问题在于您的 selectPicker.init 函数。
您需要调用选项绑定,而不是值绑定。 options.init 设置初始内部状态,当它绕过 options.update 函数时将重置该值。
// regular select and observable so call the default value binding
ko.bindingHandlers.value.init(element, valueAccessor, allBindingsAccessor);
改成
// regular select and observable so call the default value binding
ko.bindingHandlers.options.init(element, valueAccessor, allBindingsAccessor);
编辑
好的,我带你回到基础,使用标准选项绑定来获得正常的选择工作。
然后只使用 selectpicker 绑定来初始化和刷新。它将自行同步到选择。
在 Knockout 3 之前,如果元素上的任何绑定导致更新(例如更新选项、值或 selectedOptions),则将调用 selectPicker 更新函数。在 Knockout 3 中,绑定现在可以独立触发(好事),但您现在需要使用订阅来在选项或 value/selectedOptions 更改时获得通知。
我想您会发现这现在变得简单多了,并且在您的自定义绑定中单选和多选之间没有区别。如果 teamItems 或 itemID observable 被更新,这现在可以工作了。
HTML
<!-- Multiple Select -->
<select data-bind="selectedOptions: teamIDs,
options: teamItems,
optionsText: 'text',
optionsValue : 'id',
selectPicker: {}" multiple="true"></select>
JAVASCRIPT
ko.bindingHandlers.selectPicker = {
after: ['options'], /* KO 3.0 feature to ensure binding execution order */
init: function (element, valueAccessor, allBindingsAccessor) {
var $element = $(element);
$element.addClass('selectpicker').selectpicker();
var doRefresh = function() {
$element.selectpicker('refresh');
}, subscriptions = [];
// KO 3 requires subscriptions instead of relying on this binding's update
// function firing when any other binding on the element is updated.
// Add them to a subscription array so we can remove them when KO
// tears down the element. Otherwise you will have a resource leak.
var addSubscription = function(bindingKey) {
var targetObs = allBindingsAccessor.get(bindingKey);
if ( targetObs && ko.isObservable(targetObs )) {
subscriptions.push( targetObs.subscribe(doRefresh) );
}
};
addSubscription('options');
addSubscription('value'); // Single
addSubscription('selectedOptions'); // Multiple
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
while( subscriptions.length ) {
subscriptions.pop().dispose();
}
} );
},
update: function (element, valueAccessor, allBindingsAccessor) {
}
};