我想让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');
}
};
答案 0 :(得分:20)
你有两个问题:
.chosen-select
因此您的update
函数找不到select
但是无论如何您应该使用$(element)
来访问当前绑定的元素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>
请注意
{ width:'100%',... }
)在处理程序答案 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%' });
}
};