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

我正在尝试让jQuery ChosenKnockoutJS 同时工作。

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

【问题讨论】:

    标签: jquery knockout.js jquery-chosen


    【解决方案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>
    

    注意

    1. 添加了 chosen 绑定选项...而不是更改给定绑定的工作方式
    2. 选择的选项 ({ 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%' });
          }
      };
      

      【讨论】:

        猜你喜欢
        • 2014-02-21
        • 2017-12-07
        • 1970-01-01
        • 1970-01-01
        • 2016-05-24
        • 1970-01-01
        • 2020-08-28
        • 2013-07-15
        • 1970-01-01
        相关资源
        最近更新 更多