knockout 3.4 select bootstrap selectpicker

时间:2016-09-23 15:08:23

标签: twitter-bootstrap select knockout.js ko-custom-binding

为什么初始值selectPicker不能与Knockout 3.4版一起使用? 使用Knockout 3.0工作。

<select data-bind="selectPicker: teamID, items: teamItems, optionsText: 'text', optionsValue : 'id'"></select>
<div>Selected Value(s)
    <div data-bind="text: teamID"></div>
</div>
<button data-bind="click: setActive">
  Set active
</button>
<button data-bind="click: addStef">
  Add Stefan
 </button>


function ViewModel() {
var self = this;
this.teamItems = ko.observableArray([
{
    text: 'Chris',
    id: 1
},
{
    text: 'Peter',
    id: 2
},
{
    text: 'John',
    id: 3
}]);
//init value not working
this.teamID = ko.observable(3);
////
this.setActive = function () {
    this.teamID(3);
}
this.addStef = function () {
    this.teamItems.push({ text: "Stef", id: 4 })
}
}

ko.bindingHandlers.selectPicker = {
init: function (element, valueAccessor, allBindingsAccessor) {
    if ($(element).is('select')) {
        $(element).addClass('selectpicker').selectpicker();
        if (ko.isObservable(valueAccessor())) {
            if ($(element).prop('multiple') && $.isArray(ko.utils.unwrapObservable(valueAccessor()))) {
                ko.bindingHandlers.selectedOptions.init(element, valueAccessor, allBindingsAccessor);
            } else {
                ko.bindingHandlers.value.init(element, valueAccessor, allBindingsAccessor);
            }
        }
    }
},
update: function (element, valueAccessor, allBindingsAccessor) {
    if ($(element).is('select')) {
        var options = allBindingsAccessor().items;
        if (typeof options !== 'undefined' && options !== null) {
            var isDisabled = allBindingsAccessor().disable || false;
            if (ko.utils.unwrapObservable(options).length > 0) {
                // call the default Knockout options binding
                ko.bindingHandlers.options.update(element, options, allBindingsAccessor);
            }

            if (isDisabled) {
                // the dropdown is disabled and we need to reset it to its first option
                $(element).selectpicker('val', $(element).children('option:first').val());
            }
            $(element).prop('disabled', isDisabled);
        }
        if (ko.isObservable(valueAccessor())) {
            var value = ko.utils.unwrapObservable(valueAccessor());
            if ($(element).prop('multiple') && $.isArray(value)) {
                ko.bindingHandlers.selectedOptions.update(element, valueAccessor);
            } else {
                // call the default Knockout value binding
                ko.bindingHandlers.value.update(element, valueAccessor);
            }
        }

    }
}
};

ko.applyBindings(new ViewModel());

问题出在线上 this.teamID = ko.observable(3);

所选值始终与数组中的第一个元素相等。

1 个答案:

答案 0 :(得分:0)

更新回答

您可以使用options绑定,而不是包装所有选项绑定功能,这将完全正确地执行所有操作:

<select data-bind="selectPicker:true, options:teamItems, value:teamID,optionsText:'text',optionsValue:'id'"></select>

然后你的绑定处理程序只需要确保它响应对选项和值的更改:

   update: function(element, valueAccessor, allBindingsAccessor) {
     if ($(element).is('select')) {
       var isDisabled = ko.utils.unwrapObservable(allBindingsAccessor().disable);
       if (isDisabled) {
         // the dropdown is disabled and we need to reset it to its first option
         $(element).selectpicker('val', $(element).children('option:last').val());
       }
       // React to options changes
       ko.unwrap(allBindingsAccessor.get('options'));
       // React to value changes
       ko.unwrap(allBindingsAccessor.get('value'));
       // Wait a tick to refresh
       setTimeout(() => {$(element).selectpicker('refresh');}, 0);
     }
   }

原始答案:

添加the valueAllowUnset binding。在某些时候,Knockout认为所选值不在选项中,因此它将重置为第一个项目。

 <select data-bind="selectPicker:teamItems,value:teamID,optionsText:'text',optionsValue:'id',valueAllowUnset:true"></select>