我有一组复选框
>复选框A.
>复选框B.
>复选框C.
使用foreach数据绑定生成:
<input type="checkBox" data-bind="value: id,checked: $root.chkBoxSelected" />
从observableArray中获取其检查状态.所以检查一个框会将相应的值添加到数组中,标准的knockoutjs可以正常工作.然后我想添加一个简单的规则:
如果选中C,则还必须检查A和B.
在knockoutjs中添加这种逻辑的最简洁方法是什么?我尝试使用可写的可计算的observable:
var viewmodel = { foo: observableArray(),.. }; viewmodel.chkBoxSelected = ko.computed({ read: function() { return this.foo(); },write: function(value){ //add it if not added already if($.inArray(value,this.foo()) < 0) { this.foo.push(value); } // if C is present then A,B must be as well if($.inArray("C",this.foo()) >= 0) { if($.inArray("B",this.foo()) < 0) { this.foo().push("B"); } if($.inArray("A",this.foo()) < 0) { this.foo().push("A"); } } },owner: viewmodel });
在读写函数上放置一个断点:read被调用,页面加载正常.但是,当我单击任何复选框时,我收到以下错误(写断点永远不会被命中):
knockout-2.0.0.debug.js:2297 Uncaught TypeError: Object function dependentObservable() { if (arguments.length > 0) { if (typeof options["write"] === "function") { // Writing a value var valueForThis = options["owner"] || evaluatorFunctionTarget; // If undefined,it will default to "window" by convention. This might change in the future. options["write"].apply(valueForThis,arguments); } else { throw "Cannot write a value to a dependentObservable unless you specify a 'write' option. If you wish to read the current value,don't pass any parameters."; } } else { // Reading the value if (!_hasBeenEvaluated) evaluateImmediate(); ko.dependencyDetection.registerDependency(dependentObservable); return _latestValue; } } has no method 'push'
解决方法
当检查的绑定绑定到数组时,它需要能够对它执行数组操作.因此,在这种情况下使用可写的计算可观察量将导致问题.
但是,您可以选择使用手动订阅来保持项目同步.
这是一个示例视图模型:
var viewmodel = function() { var self = this; this.items = ko.observableArray([ { id: "A" },{ id: "B" },{ id: "C" },{ id: "D" } ]); this.checked = ko.observableArray(); this.checked.subscribe(function(newValue) { if (self.checked.indexOf("C") > -1) { if (self.checked.indexOf("A") < 0) { self.checked.push("A"); } if (self.checked.indexOf("B") < 0) { self.checked.push("B"); } } }); this.shouldBeDisabled = function(item) { return (item.id === "B" || item.id ==="A") && self.checked.indexOf("C") > -1; }; };
这是观点:
<ul data-bind="foreach: items"> <li> <span data-bind="text: id"></span> <input type="checkBox" data-bind="attr: { value: id },checked: $root.checked,disable: $root.shouldBeDisabled($data)" /> </li> </ul>
我使用attr:{value:id}而不是value来避免由值绑定附加的事件处理程序,因为值绑定旨在处理对字段的更改.在这种情况下,我们只想设置value属性.