jQuery Chosen doesn't update select options while working with knockout js

偶尔善良 提交于 2019-12-10 02:54:17

问题


I am trying to make jQuery Chosen and KnockoutJS work at the same time.

The problem is "jQuery Chosen" refuses to update options list even though I've created custom binding for it.

Here is the example - http://jsfiddle.net/5fGAf/

I have two changeable selects - "Country" and "Method". "Method" options list depends on country selected. When I select the country for the first time - everything works perfect. But when I want to change the country - "Method" options list remains the same, even though corresponding knockout computed value is updated.

If I manually run $(".chosen-select").trigger('chosen:updated') in the browser console - options list updates.

Custom binding code:

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

回答1:


You have two problems:

  • in your fiddle there is no .chosen-select so your update function does not find the select but anyway you should use $(element) to access the currently bound element
  • in KO 3.0 bindings are fired independently. Because your chosen binding is not connected to the your observable array your update won't fire when you change that array.

You can solve this "update" problem with explicitly declaring a dependency on the options binding in your custom binding but a better solution would be to delegate to it:

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

And use it where you would normally use the options binding:

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

Demo JSFiddle.




回答2:


My solution is this:

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

You'd use it like so:

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

Note that

  1. The chosen binding is option is added...rather than changing the way the given binding works
  2. Chosen options ({ width:'100%',... }) are not hardwired in the handler



回答3:


I used a method that is also compatible with all my existing bindings, so I didn't need to go though a ton of html files removing the options binding.

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%' });
    }
};


来源:https://stackoverflow.com/questions/22022261/jquery-chosen-doesnt-update-select-options-while-working-with-knockout-js

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!