我使用带有knockout.js的Select2。
但是控件并没有显示正确的初始值。看起来似乎没有引发选择功能
我修改了现有的jsbin来演示我的问题。
http://jsbin.com/xufovura/6/edit
绑定:
<div data-bind="value: selectedState, select2: { data: states, placeholder: 'Select a State', formatResult: format ,initSelection: initSelect}" class="select2" style="width: 200px"></div>
自定义绑定的一部分(jsbin中的完整代码):
ko.bindingHandlers.select2 = {
init: function(el, valueAccessor, allBindingsAccessor, viewModel) {
ko.utils.domNodeDisposal.addDisposeCallback(el, function() {
$(el).select2('destroy');
});
var allBindings = allBindingsAccessor(),
select2 = ko.utils.unwrapObservable(allBindings.select2);
$(el).select2(select2);
}
};
function initSelect(element, callback) {
console.log("initSelect");
var selectedItems = $.grep(this.states, function (e) { return e.id == element.id; });
console.log(element);
callback(selectedItems[0]);
}
答案 0 :(得分:3)
未调用initSelect函数的原因是Select2认为您的占位符已被选中。 Select2读取$(element).val()
,如果结果为假,则认为占位符被选中。
对于val()结果,您的div元素将始终返回“”。
您应该将div元素切换为输入元素,但是当我在jsBin中执行此操作时,我发现输入的值尚未被knockout初始化。这是值绑定的计时问题,因为在调用select2绑定的init函数时尚未调用值绑定的更新函数。
Knockout首先调用所有init函数,然后调用更新函数。
当不使用选择元素时,Select2与Knockout的效果不佳!!
快速而肮脏的解决方案是确保在调用select2插件之前设置了元素的值。
init: function(el, valueAccessor, allBindingsAccessor, viewModel) {
ko.utils.domNodeDisposal.addDisposeCallback(el, function() {
$(el).select2('destroy');
});
var allBindings = allBindingsAccessor(),
select2 = ko.utils.unwrapObservable(allBindings.select2);
// Ensure the input's value is set before calling select2
$(el).val(allBindings.value());
$(el).select2(select2);
}
您也不再需要initSelected选项,事实上由于$.grep(this.states, ...)
而导致jsBin失败,“此”此时并未引用视图模型。
您还需要注意,当移动到Knockout 3.x时allBindingsAccessor会发生变化
更长更完整的答案包括为各种select2事件设置处理程序,以及手动订阅支持值,以便在绑定的更新方法需要时协调手动调用$(el).select2('data', ...)
。
如果您将后备存储更改为对象而不仅仅是字符串值(即存储实际的“状态”对象,而不仅仅是它的id),也需要此方法