Select2 allowclear and knockout.js
Select2 allowclear and knockout.js
我使用这个简单的绑定select2和knockoutJs:
ko.bindingHandlers.select2 = {
init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
var options = ko.toJS(valueAccessor()) || {};
setTimeout(function () {
$(element).select2(options);
}, 0);
}
};
标记:
<select class="select2" style="width:100%" data-bind="optionsCaption: '',options: $root.items,optionsText: 'description',optionsValue: 'id', value: $root.selectedItem,select2: { placeholder: 'Select an item...',allowClear: true }"></select>
它工作!现在我在Select2中启用allowClear
选项,以清除下拉到占位符值,如Select an item...
。
如果我点击x
图标下拉正确设置占位符,但淘汰不更新可观察的绑定值!
我想我必须改变自定义绑定,添加这样的东西:
setTimeout(function () {
$(element).select2(options).on("select2-removed", function (e) {
ko.bindingHandlers.value.update(element, function () { return ''; });
});
...
但是行不通!
有几个问题。
1)在bindinghandler的update
是更新DOM基于值的变化,你不应该定义一个update
回调与能力改变你的模型。
正确的方法是,当定义一个新的bindinghandler时,使用init
回调将所有change
事件与模型挂钩,update
回调仅仅是一个DOM绘制例程。
如果您的init
提供DOM绘图(如select2提供),您不需要定义update
回调。
因此ko.bindingHandlers.value.update(element, function () { return ''; });
行只重新绘制DOM,它不做您想要的。
2)您创建的select2
绑定有一些孔。
- 首先,
value
绑定不知道select2
绑定的存在,这就是你挣扎的地方。 - 第二,您的
select2
绑定必须等待其他绑定(options
绑定)完成DOM创建,这就是为什么您使用setTimeout
。但是ko提供了一种定义绑定序列的方法,看看ko value
绑定的源代码,它被定义为'after': ['options', 'foreach']
- 第三,你的select2不响应外部的变化。例如,如果你有另一个UI来更新
$root.selectedItem
(一个普通的选择列表),由该UI引发的更改将不会同步回你的select2。
基于现有的value
绑定定义select2
绑定(刚发现不需要),并连接所有更改事件
- 我们不需要
-
select2
提供了所有的图纸,我们不需要update
回调。 - 使用
shouldIgnore
标志来打破value subscriber和select2 change event handler之间的循环。
"select2-removed"
事件,我们只需要"change"
事件。<> http://jsfiddle.net/huocp/8N3zX/6/http://jsfiddle.net/huocp/8N3zX/9/
ko.bindingHandlers.valueSelect2 = {
'after': ['options'],
'init': function(element, valueAccessor, allBindings) {
// kind of extend value binding
// ko.bindingHandlers.value.init(element, valueAccessor, allBindings);
var options = allBindings.get('select2Options') || {};
$(element).select2(options);
var value = valueAccessor();
// init val
$(element).val(ko.unwrap(value)).trigger("change");
var changeListener;
if (ko.isObservable(value)) {
var shouldIgnore = false;
changeListener = value.subscribe(function(newVal) {
if (! shouldIgnore) {
shouldIgnore = true;
// this is just select2 syntax
$(element).val(newVal).trigger("change");
shouldIgnore = false;
}
});
// this demo only works on single select.
$(element).on("change", function(e) {
if (! shouldIgnore) {
shouldIgnore = true;
if (e.val == '') {
// select2 use empty string for unselected value
// it could cause problem when you really want '' as a valid option
value(undefined);
} else {
value(e.val);
}
shouldIgnore = false;
}
});
}
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
if (changeListener) changeListener.dispose();
$(element).select2("destory");
});
}
};
相关文章:
- 无法获取属性'Id'使用Knockout.js的未定义或空引用API
- 如何将Knockout.JS与服务器已经在DOM中呈现的数据同步
- Knockout.JS标签在foreach内部不起作用
- 使用Knockout JS从下拉框中向observalearray添加项
- 使用knockout.js将数组绑定到视图模型
- 如何使用Jasmine测试Knockout.js点击绑定
- 类似于Prism的Knockout js框架
- Knockout JS和简单的函数
- Knockout.js中带有if:子句的嵌套循环
- Knockout JS中具有下拉列表的数组
- Knockout.JS,模板都是通过表单不添加数据的
- 在Knockout JS中搜索从DB加载数据的项目
- 使用Knockout.js动态更改facebook数据
- $root在knockout.js中解析为空白页
- knockout.js中的绑定多下拉列表
- 在Knockout js中创建一个包含多行的表,而不需要推送
- 如何基于Knockout js模型设计控件样式
- 从对象内部调用knockout.js ko.applyBindings()
- Breeze.js + Knockout.js Tutorials
- 不能动态加载jquery, bootstrap, D3.js, knockout.js的CDN