2014-02-25 124 views
10

我正在努力使jQuery ChosenKnockoutJS在同一时间工作。jQuery Chosen不使用淘汰js更新选择选项

问题是“jQuery Chosen”拒绝更新选项列表,即使我已经为它创建了自定义绑定。

这里是例子 - http://jsfiddle.net/5fGAf/

我有两个选择多变 - “国家”和“方法”。 “方法”选项列表取决于选择的国家。当我第一次选择国家时 - 一切都很完美。但是当我想改变国家 - “方法”选项列表保持不变,即使相应的敲除计算值被更新。

如果我在浏览器控制台中手动运行$(".chosen-select").trigger('chosen:updated') - 选项列表更新。

自定义代码:

ko.bindingHandlers.chosen = { 
    init: function(element) {    
    $(element).chosen({disable_search_threshold: 10}); 
    }, 
    update: function(element) { 
    $(".chosen-select").trigger('chosen:updated'); 
    } 
}; 

回答

19

你有两个问题:

    在提琴
  • 没有.chosen-select所以你update功能没有找到select但无论如何,你应该使用$(element)访问当前绑定元素
  • in KO 3.0 bindings are fired independently。由于您的chosen绑定未连接到您的可观察阵列,因此您在更改该阵列时不会触发update

可以解决这一“更新”问题,明确声明绑定在options依赖于你的自定义绑定,但一个更好的解决办法是委托给它:

ko.bindingHandlers.chosen = { 
    init: function(element) { 
     ko.bindingHandlers.options.init(element); 
     $(element).chosen({disable_search_threshold: 10}); 
    }, 
    update: function(element, valueAccessor, allBindings) { 
     ko.bindingHandlers.options.update(element, valueAccessor, allBindings); 
     $(element).trigger('chosen:updated'); 
    } 
}; 

并使用它,你通常使用的options结合:

<select id="option1" class="form-control" 
    data-bind="chosen: payoutOptions, 
       optionsText: 'optionText', 
       optionsValue: 'optionValue', 
       value: activePayoutOption"></select> 

演示JSFiddle

+0

在使用该解决方案面临的问题的方式 - 如果观察到,负责选择选择选项reseted('observableVariable( null)') - 选择不正确更新。这里是例子 - [JSFiddle](http://jsfiddle.net/VxMqV/)。提前致谢! – Shtirlits

+2

问题有两方面:一方面,自KO 3.0以来,当您选择的observable发生更改时,您的自定义更新不会触发,而另一方面,如果选择值发生变化,选定的插件不会自动处理。所以你需要手动订阅'value'绑定,并在底层observable发生变化时触发'selected:update':这是一个使用更新的绑定处理函数的示例:http://jsfiddle.net/SWEt2/ – nemesv

+0

优秀的答案nemesv - 希望如果有其他人遇到此问题,他们会赞成,因为这是一个比较高评分的Google结果更好的解决方案。 –

2

我使用的方法也与我现有的所有绑定兼容,所以我不需要通过大量的html文件去除options绑定。

ko.bindingHandlers.chosen = { 
    init: function(element, valueAccessor, allBindings) { 
     $(element).chosen({ disable_search_threshold: 10}); 
     var valueObservable = allBindings.get('value'); 
     var optionsObservable = allBindings.get('options'); 

     var updateList = function() { 
      $(element).trigger('chosen:updated'); 
     } 

     if (valueObservable && typeof(valueObservable.subscribe) == 'function') { 
      valueObservable.subscribe(updateList); 
     } 

     if (optionsObservable && typeof(optionsObservable.subscribe) == 'function') { 
      optionsObservable.subscribe(updateList); 
     } 

     $(element).chosen({ disable_search_threshold: 7, width:'100%' }); 
    } 
}; 
8

我的解决办法是这样的:

ko.bindingHandlers.chosen = 
{ 
    init: function (element, valueAccessor, allBindings) { 
     $(element).chosen(valueAccessor()); 

     // trigger chosen:updated event when the bound value or options changes 

     $.each('value|selectedOptions|options'.split("|"), function (i, e) { 
      var bv = allBindings.get(e); 
      if (ko.isObservable(bv)) 
       bv.subscribe(function() { $(element).trigger('chosen:updated'); }); 
     }); 
    }, 
    update: function (element) { 
     $(element).trigger('chosen:updated'); 
    } 
}; 

你会使用它,像这样:

<select data-bind=" 
    options: payoutOptions, 
    optionsText: 'optionText', 
    optionsValue: 'optionValue', 
    value: activePayoutOption, 
    chosen: { disable_search_threshold: 10, width:'100%' }"> 
</select> 

注意

  1. 选择绑定选项添加...而不是改变给定的绑定工作,
  2. 选的选项({ width:'100%',... })未在处理硬