如何将复选框绑定到值的反转?

Sha*_*ake 5 javascript knockout.js

我有一个案例,当我需要将一个复选框和另一个DOM元素的可见性绑定到我的viewModel的布尔属性的反转时:

<input type="checkbox" data-bind="checked: needsReview"> Not Required 
<br>
<div id="Some related text" data-bind="visible: needsReview"> other stuff here </div>
Run Code Online (Sandbox Code Playgroud)
var dataFromSever = { needsReview: true };

var theModel = function (jsonData) {
    var self = this;
    ko.mapping.fromJS(jsonData, {}, self);
}

ko.applyBindings(new theModel(dataFromSever));
Run Code Online (Sandbox Code Playgroud)

在我的实际数据模型中,我有多个这样的属性,所以我不想创建多个ko.computed()字段.我只想绑定"checked: !needsReview()"或维护同样简单的东西.

RP *_*yer 13

有几种类似的方法来处理这个.基本思想是你需要创建一个可写的计算observable来绑定复选框.

您可以直接在模型中使用扩展程序或通过向可观察基础(ko.observable.fn)添加函数来完成此操作.

但是,由于您使用的是映射插件,并且可能不希望自定义创建对象的方式或添加其他属性,因此我认为使用自定义绑定是最佳选择.您的模型实际上不需要关心保持与您的属性的反转,因此我们实际上可以在绑定时执行此部分.

这是一个inverseChecked绑定,在您的真正的可观察和绑定之间插入一个可写的计算的observable.然后,它只是使用真正检查的绑定来完成它的工作.

ko.bindingHandlers.inverseChecked = {
    init: function(element, valueAccessor, allBindingsAccessor) {
        var value = valueAccessor();
        var interceptor = ko.computed({
                            read: function() {
                                return !value();
                            },
                            write: function(newValue) {
                                value(!newValue);
                            },
                            disposeWhenNodeIsRemoved: element
                        }); 

        var newValueAccessor = function() { return interceptor; };


        //keep a reference, so we can use in update function
        ko.utils.domData.set(element, "newValueAccessor", newValueAccessor);
        //call the real checked binding's init with the interceptor instead of our real observable
        ko.bindingHandlers.checked.init(element, newValueAccessor, allBindingsAccessor);
    },
    update: function(element, valueAccessor) {
        //call the real checked binding's update with our interceptor instead of our real observable
        ko.bindingHandlers.checked.update(element, ko.utils.domData.get(element, "newValueAccessor"));  
    }
};
Run Code Online (Sandbox Code Playgroud)

这是一个示例:http://jsfiddle.net/rniemeyer/Kz4Tf/

为了您的visible结合,你可以做visible: !needsReview()

  • 谢谢.这看起来正是我需要的.它真的看起来应该比这更简单,不是吗?我会看看今天早上我是否无法连线... (3认同)
  • 这似乎不适用于KO v3.只是试了一下,没有运气.这是一个简单的修复,只需使用`ko.bindingHandlers.checked.init`而不是`update`. (3认同)