如何将复选框绑定到值的倒数? [英] How to bind a checkbox to the inverse of a value?

查看:56
本文介绍了如何将复选框绑定到值的倒数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一种情况,当我需要将一个复选框和另一个DOM元素的可见性绑定到我的viewModel的boolean属性的倒数时:

 <input type="checkbox" data-bind="checked: needsReview"> Not Required 
<br>
<div id="Some related text" data-bind="visible: needsReview"> other stuff here </div>
 

 var dataFromSever = { needsReview: true };

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

ko.applyBindings(new theModel(dataFromSever));
 

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

解决方案

有几种类似的方法可以处理此问题.基本思想是您需要创建一个可写的可计算观察值,以将复选框绑定到该值.

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

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

这里是inverseChecked绑定,它在您的实际可观察​​对象和绑定之间插入可写计算可观察对象.然后,它仅使用实际的检查绑定进行工作.

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"));  
    }
};

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

对于visible绑定,您可以执行visible: !needsReview()

I have a case when I need to bind a checkbox and the visibility of another DOM element to the inverse of a boolean property of my viewModel:

<input type="checkbox" data-bind="checked: needsReview"> Not Required 
<br>
<div id="Some related text" data-bind="visible: needsReview"> other stuff here </div>

var dataFromSever = { needsReview: true };

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

ko.applyBindings(new theModel(dataFromSever));

I have more than one property like this in my actual data model, so I do not want to make multiple ko.computed() fields. I'd just like to bind to "checked: !needsReview()" or something equally simple to maintain.

解决方案

There are a few similar ways to handle this one. The basic idea is that you need to create a writeable computed observable to bind the checkbox against.

You could do this in your model directly, using an extender, or by adding a function to the observable base (ko.observable.fn).

However, since you are using the mapping plugin and likely don't want to customize the way that your objects are created or add additional properties, I think that using a custom binding is the best option. Your model really does not need to be concerned with maintaining an inverse to your property, so we can actually do this part while binding.

Here is an inverseChecked binding that inserts a writeable computed observable between your real observable and the binding. Then, it simply uses the real checked binding to do its work.

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"));  
    }
};

Here is a sample: http://jsfiddle.net/rniemeyer/Kz4Tf/

For your visible binding you can do visible: !needsReview()

这篇关于如何将复选框绑定到值的倒数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆