选择具有Knockout.js初始值的2

时间:2014-06-11 18:27:27

标签: javascript jquery knockout.js jquery-select2

我使用带有knockout.js的Select2。

但是控件并没有显示正确的初始值。看起来似乎没有引发选择功能

我修改了现有的jsbin来演示我的问题。

http://jsbin.com/xufovura/6/edit

绑定:

<div data-bind="value: selectedState, select2: { data: states, placeholder: 'Select a State', formatResult: format ,initSelection: initSelect}" class="select2" style="width: 200px"></div>

自定义绑定的一部分(jsbin中的完整代码):

ko.bindingHandlers.select2 = {
    init: function(el, valueAccessor, allBindingsAccessor, viewModel) {
      ko.utils.domNodeDisposal.addDisposeCallback(el, function() {
    $(el).select2('destroy');
});

            var allBindings = allBindingsAccessor(),
            select2 = ko.utils.unwrapObservable(allBindings.select2);

      $(el).select2(select2);

    }
};

 function initSelect(element, callback) {
   console.log("initSelect");
          var selectedItems = $.grep(this.states, function (e) { return e.id == element.id; });

           console.log(element);


            callback(selectedItems[0]);
        }

1 个答案:

答案 0 :(得分:3)

未调用initSelect函数的原因是Select2认为您的占位符已被选中。 Select2读取$(element).val(),如果结果为假,则认为占位符被选中。

对于val()结果,您的div元素将始终返回“”。

您应该将div元素切换为输入元素,但是当我在jsBin中执行此操作时,我发现输入的值尚未被knockout初始化。这是值绑定的计时问题,因为在调用select2绑定的init函数时尚未调用值绑定的更新函数。

Knockout首先调用所有init函数,然后调用更新函数。

当不使用选择元素时,Select2与Knockout的效果不佳!!

快速而肮脏的解决方案是确保在调用select2插件之前设置了元素的值。

init: function(el, valueAccessor, allBindingsAccessor, viewModel) {
  ko.utils.domNodeDisposal.addDisposeCallback(el, function() {
    $(el).select2('destroy');
  });

  var allBindings = allBindingsAccessor(),
  select2 = ko.utils.unwrapObservable(allBindings.select2);

  // Ensure the input's value is set before calling select2
  $(el).val(allBindings.value());
  $(el).select2(select2);      
}

您也不再需要initSelected选项,事实上由于$.grep(this.states, ...)而导致jsBin失败,“此”此时并未引用视图模型。

您还需要注意,当移动到Knockout 3.x时allBindingsAccessor会发生变化


更长更完整的答案包括为各种select2事件设置处理程序,以及手动订阅支持值,以便在绑定的更新方法需要时协调手动调用$(el).select2('data', ...)

如果您将后备存储更改为对象而不仅仅是字符串值(即存储实际的“状态”对象,而不仅仅是它的id),也需要此方法