使用knockout js时,jQuery Chosen不会更新选择选项

时间:2014-02-25 17:54:38

标签: jquery knockout.js jquery-chosen

我想让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');
  }
};

3 个答案:

答案 0 :(得分:20)

你有两个问题:

  • 在您的小提琴中没有.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

答案 1 :(得分: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%',... })在处理程序
  3. 中没有硬连线

答案 2 :(得分: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%' });
    }
};