JQuery Chosen не обновляет опции выбора при работе с нокаутом js
Я пытаюсь сделать 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 запускаются независимо. Поскольку привязка
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.
Ответ 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>
Обратите внимание, что
- Выбранная привязка - опция добавлена ... вместо того, чтобы изменять способ работы с данными.
- Выбранные опции (
{ 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%' });
}
};