2015-03-02 60 views
0

我对这个处理程序有困难,我已经部分从这里获得并部分被黑客入侵。我仍然对处理程序感兴趣,所以我认为我的问题源于缺乏理解。使用延迟加载淘汰多选下拉列表

我在ko“if”语句中显示的模板中使用此处理函数。当模板被包含/排除时,选项是重复的。这是因为unwrap(valueAccessor()).push(item)行。我已经尝试过独立构建数组,然后直接将valueAccessors的值设置为数组,但ui没有响应,它只能通过推送项来工作。

我该如何解决这个问题?我是否正确地进行了绑定,还是有更合适的方法?我已经用注释标记了代码行,以指出我的问题发生在哪里。

multiSelectCheck: { 
     init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
      // This will be called when the binding is first applied to an element 
      // Set up any initial state, event handlers, etc. here 
      var bindings = allBindingsAccessor(); 
      var ddOptions = unwrap(valueAccessor); 
      var selectedOptions = unwrap(bindings.selectedOptions); 
      var options = unwrap(bindings.multiselectOptions) || []; 
      var optionsCaption = unwrap(bindings.optionsCaption); 
      var displaySelected = unwrap(bindings.selectedList) || 5; 
      var loadingCaption = unwrap(bindings.loadingCaption); 
      var delimiter = unwrap(bindings.splitSelectedBy) || ','; 
      var setInitial = unwrap(bindings.setInitialValue); 

      // display loader in dropdown 
      ko.computed(function() { 
       if (unwrap(bindings.loading)) { 
        var spinnerClass = 'fa fa-spinner fa-spin fa-lg'; 
        var spinner = loadingCaption || '<span><i class="' + spinnerClass + '"></i> Loading...</span>'; 

        // set text to loading 
        $(element).multiselect({ selectedList: 0, noneSelectedText: spinner, selectedText: spinner }).multiselect('disable'); 
        $(element).multiselect('refresh'); 
       } 
      }, null, { disposeWhenNodeIsRemoved: element }); 

      // internal options 
      var internal = { selectedList: displaySelected, noneSelectedText: 'Select options', selectedText: '# selected' } 

      // merge options with provided options 
      options = $.extend(internal, options); 

      // pass the original optionsCaption to the similar widget option 
      if (optionsCaption) { 
       options.noneSelectedText = unwrap(optionsCaption); 
      } 

      // remove this and use the widget's 
      bindings.optionsCaption = ''; 

      // populate intitial values if available 
      if (ddOptions && !ddOptions.length && setInitial) { 

       if (selectedOptions) { 

        // create array from value 
        if (typeof selectedOptions == 'string') { 
         selectedOptions = selectedOptions.split(delimiter); 
         selectedOptions = selectedOptions.filter(function (e) { return !!e; }); // filter empty nodes 
         bindings.selectedOptions(selectedOptions); 
        } 

        // add options objects to array of available options 
        for (var i = 0; i < selectedOptions.length; i++) { 
         var item = { Value: selectedOptions[i], Text: '' }; 
         //console.log(item); 

         //#### THIS IS THE LINE OF CODE IN QUESTION #### 
         unwrap(valueAccessor()).push(item); 
        } 
       } 
      } 

      // apply multiselect plugin 
      var elm = $(element).multiselect(options).multiselectfilter({ filterOnly: true, autoReset: true }); 

      // refresh the plugin 
      $(element).multiselect('refresh'); 

      ko.utils.domNodeDisposal.addDisposeCallback(element, function() { 
       elm.multiselectfilter('destroy').multiselect("destroy"); 
       $(element).remove(); 
      }); 

     }, 
     update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
      // This will be called once when the binding is first applied to an element, 
      // and again whenever the associated observable changes value. 
      // Update the DOM element based on the supplied values here. 
      var bindings = allBindingsAccessor(); 
      var selectOptions = unwrap(bindings.multiSelectCheck); 
      var selectedOptions = unwrap(bindings.selectedOptions); 
      var delimiter = unwrap(bindings.splitSelectedBy) || ','; 
      var displaySelected = unwrap(bindings.selectedList) || 5; 

      // remove this and use the widget's 
      bindings.optionsCaption = ''; 

      // handle delimited values 
      if (typeof selectedOptions == 'string') { 
       selectedOptions = selectedOptions.split(delimiter); 
       selectedOptions = selectedOptions.filter(function (e) { return !!e; }); // filter empty nodes 
       bindings.selectedOptions(selectedOptions); 
      } 

      ko.bindingHandlers.options.update(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext); 
      var data = unwrap(valueAccessor()); 
      var showFilter = (data && data.length > 10) ? 'enable' : 'disable'; 

      setTimeout(function() { 
       var $element = $(element); 
       $element.multiselect({ selectedList: displaySelected, noneSelectedText: 'Select options', selectedText: '# selected' }).multiselect('enable').multiselect('refresh').multiselectfilter('refresh'); 
       $element.multiselectfilter(showFilter); 
       $element.multiselect('refresh'); 
      }, 0); 
     } 
    } 

回答

0

尝试创建项目和更新valueAccessor观察到的直接阵列临时数组:

var items = []; 
for (var i = 0; i < selectedOptions.length; i++) { 
    items.push({ Value: selectedOptions[i], Text: '' }); 
} 

// items 
valueAccessor(items); 
+0

我已经试过这很好,但该值不进行更新。我也尝试将valueAccessor设置为一个空白数组,然后添加初始值,但那也没有奏效。 :/ – Tony 2015-03-03 13:53:05

0

所以我的问题结束了,我认为我有数组值,但是我最终具有可观察代替。这导致我的数组长度检查始终通过,所以它不断添加初始值。

我不得不改变的init线

var ddOptions = unwrap(valueAccessor); 

var ddOptions = unwrap(valueAccessor()); // added() :/