jQuery Chosen 在使用淘汰赛 js 时不会更新选择选项

Posted

技术标签:

【中文标题】jQuery Chosen 在使用淘汰赛 js 时不会更新选择选项【英文标题】:jQuery Chosen doesn't update select options while working with knockout js 【发布时间】:2014-03-28 03:38:59 【问题描述】:

我正在尝试让jQuery Chosen 和KnockoutJS 同时工作。

问题是“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');
  
;

【问题讨论】:

【参考方案1】:

你有两个问题:

在你的小提琴中没有.chosen-select 所以你的update 函数找不到select 但无论如何你应该使用$(element) 来访问当前绑定的元素 在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.

【讨论】:

在使用此解决方案时遇到问题 - 如果可观察到,负责选择的选项已重置 (observableVariable(null)) - 无法正确更新。这是示例 - JSFiddle。提前致谢! 问题是双重的:一方面,从 KO 3.0 开始,当您选择的 observable 发生更改时,您的自定义更新不会触发,另一方面,如果选择值发生更改,则选择的插件不会自动处理。因此,您需要手动订阅 value 绑定并在底层 observable 更改时触发 chosen:update:这是使用更新的绑定处理程序的示例:jsfiddle.net/SWEt2 优秀的答案 nemesv - 希望如果其他人遇到这个问题,他们会投票赞成,因为它是比 Google 评分更高的结果更好的解决方案。 @nemesv 小提琴的一个问题似乎是,如果您使用 optionsCaption,它会在没有选项绑定的情况下清除下拉列表的值。 jsfiddle.net/VxMqV/6 有什么想法吗? 在我的情况下,chosen:updated 值更改时触发事件,不会更新所选选项。有什么想法吗?【参考方案2】:

我的解决办法是这样的:

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>

注意

    添加了 chosen 绑定选项...而不是更改给定绑定的工作方式 选择的选项 ( width:'100%',... ) 在处理程序中没有硬连线

【讨论】:

【参考方案3】:

我使用的方法也与我现有的所有绑定兼容,因此我不需要通过大量的 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%' );
    
;

【讨论】:

以上是关于jQuery Chosen 在使用淘汰赛 js 时不会更新选择选项的主要内容,如果未能解决你的问题,请参考以下文章

chosen.jquery.js 使用笔记

jquery.chosen.js下拉选择框美化插件项目实例

jQuery Chosen 使用

Chosen.js 可以搜索选项的值及其文本吗?

chose.jquery 联动

使用带有 jquery ui 滑块的淘汰赛 js