不确定复选框的Knockout自定义绑定不起作用
Knockout custom binding for indeterminate checkbox won't work
让我们简单地说:这是我的knockout自定义绑定,用于将复选框置于不确定状态。
ko.bindingHandlers.nullableChecked = {
update: function (element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
if (value == null) element.indeterminate = true;
ko.bindingHandlers.checked.update(element, function () { return value; });
}
};
如果初始值是null
,一切工作正常,复选框处于不确定状态,但当我单击复选框时,它似乎不会相应地更新绑定属性的值为false/true。我错过什么了吗?
如果有人在这里希望有一个select all type复选框作为中间显示,如果不是所有的子项目都被选中,你可以使用一个简单的绑定,像这样
ko.bindingHandlers.indeterminateValue = {
update: function (element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
element.indeterminate = value;
}
};
那么你可以这样使用
<input type="checkbox" data-bind="checked: selectedAllProduce, indeterminateValue: selectedProduce().length > 0 && selectedProduce().length < produce.length" title="Select all/none"/>
下面是一个显示它在计算的可观察对象select all上工作的例子https://jsfiddle.net/deannorth/crqwac12/
@Fodagus的答案适用于Knockout <= 2.3.0,但在Knockout>= 3.0.0中,ko.bindingHandlers.checked.update
是未定义的。
我们发现这在Knockout 3.1.0中适用:
ko.bindingHandlers.nullableChecked = {
init: function (element, valueAccessor) {
ko.bindingHandlers.checked.init(element, valueAccessor);
},
update: function (element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
if (value == null) {
element.indeterminate = true;
}
else {
element.indeterminate = false;
}
}
};
我们错过了什么吗?
您没有调用Init。
只需在nullableChecked init函数中为checked代理init函数,就像您在更新中所做的那样。
ko.bindingHandlers.nullableChecked = {
init: function(element, valueAccessor) {
ko.bindingHandlers.checked.init(element, valueAccessor);
},
update: function (element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
if (value == null) element.indeterminate = true;
ko.bindingHandlers.checked.update(element, valueAccessor);
}
};
如果没有init,它永远不会在复选框上设置一个"click"绑定来告诉knockout发生了变化。如果您查看调试代码(http://knockoutjs.com/downloads/knockout-2.2.1.debug.js),您将看到init使用jQuery在复选框上设置一个'click'事件,以便在值发生变化时更新可观察对象。
ko.bindingHandlers['checked'] = {
'init': function (element, valueAccessor, allBindingsAccessor) {
var updateHandler = function() {
var valueToWrite;
if (element.type == "checkbox") {
valueToWrite = element.checked;
} else if ((element.type == "radio") && (element.checked)) {
valueToWrite = element.value;
} else {
return; // "checked" binding only responds to checkboxes and selected radio buttons
}
var modelValue = valueAccessor(), unwrappedValue = ko.utils.unwrapObservable(modelValue);
if ((element.type == "checkbox") && (unwrappedValue instanceof Array)) {
// For checkboxes bound to an array, we add/remove the checkbox value to that array
// This works for both observable and non-observable arrays
var existingEntryIndex = ko.utils.arrayIndexOf(unwrappedValue, element.value);
if (element.checked && (existingEntryIndex < 0))
modelValue.push(element.value);
else if ((!element.checked) && (existingEntryIndex >= 0))
modelValue.splice(existingEntryIndex, 1);
} else {
ko.expressionRewriting.writeValueToProperty(modelValue, allBindingsAccessor, 'checked', valueToWrite, true);
}
};
ko.utils.registerEventHandler(element, "click", updateHandler);
// IE 6 won't allow radio buttons to be selected unless they have a name
if ((element.type == "radio") && !element.name)
ko.bindingHandlers['uniqueName']['init'](element, function() { return true });
},
编辑:这是一个小提琴:http://jsfiddle.net/cclose/NFfVn/
新版knockout 3.0.0
及以上版本。删除了checkbox
绑定处理程序中的更新方法。因此,您应该在init
函数中创建click event
,以便在单击checkbox
时触发更新方法。下面是一个将jquery checkbox
转换为uniform checkbox
的绑定处理程序的示例。
ko.bindingHandlers.checkedUniform =
{
init: function (element, valueAccessor) {
ko.bindingHandlers.checked.init(element, valueAccessor);
$(element).uniform().on('click', ko.bindingHandlers.checkedUniform.update);
},
update: function (element, valueAccessor)
{
ko.bindingHandlers.checked.update(element, valueAccessor);
$.uniform.update($(element));
}
};
checked
处理程序接收到存储的值的访问器,而不是保存该值的可观察对象。因此,可观察对象永远不会得到任何由处理程序引起的值变化。我认为你应该能够直接传递值访问器
ko.bindingHandlers.nullableChecked = {
update: function (element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
if (value == null) element.indeterminate = true;
ko.bindingHandlers.checked.update(element, valueAccessor);
}
};
- 对象文字方法上的Javascript绑定不起作用
- Knockout输入绑定不起作用
- 角度指令双向绑定不起作用
- 指令中选择输入的双向绑定不起作用
- Angularjs:ui路由嵌套状态下的绑定不起作用
- 为什么我的淘汰选项绑定不起作用
- jQuery Ajax 元素的后期绑定不起作用
- 样式绑定不起作用
- 在内联编辑的情况下,Knockout绑定不起作用
- 指令链接中的绑定不起作用
- Angular 1.5组件双向绑定不起作用
- 点击处理程序多次触发,解除绑定不起作用
- KnockoutJS - 引导程序 3 模式绑定不起作用
- foreach:绑定不起作用 ko.mapping.fromJS 数据
- 虚拟元素的挖空绑定不起作用
- 委托的“模板”绑定不起作用
- Angularjs 双向数据绑定不起作用;$watch也不起作用
- 使用 D3js 时,带有 DOM 的 AngularJS 数据绑定不起作用
- 视频播放事件中的 Angular 2 路绑定不起作用
- 如果语句和挖空中的可见绑定不起作用