简体   繁体   English

Select2具有Knockout.js初始值

[英]Select2 with Knockout.js inital value

i use Select2 with knockout.js. 我将Select2与kickout.js一起使用。

But the control doesn't show the initial value right. 但是控件没有正确显示初始值。 It looks like the select function isnt raised 似乎没有引发选择功能

I modified an existing jsbin to demonstrate my problem. 我修改了一个现有的jsbin来演示我的问题。

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

The binding: 绑定:

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

part of the custom binding (complete code in the jsbin): 自定义绑定的一部分(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]);
        }

The reason your initSelect function is not invoked is that Select2 thinks that your placeholder is selected. 未调用initSelect函数的原因是Select2认为已选择了您的占位符。 Select2 reads $(element).val() and if that result is falsey then the placeholder is deemed to be selected. Select2读取$(element).val() ,如果结果为false,则认为该占位符已被选中。

Your div element will always return "" for the val() result. 您的div元素将始终为val()结果返回“”。

You should switch the div element to an input element, however when I did this in your jsBin then I found that the input's value had not been initialized by knockout. 您应该将div元素切换为输入元素,但是当我在jsBin中执行此操作时,我发现输入的值尚未通过敲除进行初始化。 This is a timing issue with the value binding as the value binding's update function has not yet been invoked when select2 binding's init function is called. 这是值绑定的时间问题,因为调用select2绑定的init函数时尚未调用值绑定的更新函数。

Knockout calls all the init functions first, then the update functions. 淘汰赛首先调用所有初始化函数,然后调用更新函数。

Select2 doesn't play nice with Knockout when not using a select element !! 不使用select元素时,Select2在淘汰赛中表现不佳!

A quick and dirty solution is to make sure that the element's value is set before calling select2 plugin. 一种快速而肮脏的解决方案是在调用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);      
}

You also don't need the initSelected option anymore, and in fact your fails in the jsBin due to $.grep(this.states, ...) "this" does not refer to the view model at that point. 您也不再需要initSelected选项,实际上,由于$.grep(this.states, ...)而导致的jsBin失败,此时“ this”未引用视图模型。

You also need to take note that allBindingsAccessor changes when moving to Knockout 3.x 您还需要注意,移至Knockout 3.x时allBindingsAccessor会更改


The longer and more complete answer involves setting up handlers to various select2 events, and a manual subscription to the backing value to coordinate the manual invocation to $(el).select2('data', ...) when required from the update method of your bindings. 更长,更完整的答案包括设置处理程序以处理各种select2事件,以及手动订阅支持值,以在更新方法需要时将手动调用与$(el).select2('data', ...)进行协调$(el).select2('data', ...)您的绑定。

This approach will also be required should you change the backing store to an object instead of just a string value ( ie store the actual "state" object, not just it's id ) 如果将后备存储更改为对象而不是仅更改为字符串值(例如,存储实际的“状态”对象,而不仅仅是其id),则也需要这种方法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM