Knockoutjs计算了传递参数

Qai*_*har 42 javascript binding observable knockout.js

我想知道在绑定时是否有可能使用knockoutjs来传递参数.

我绑定了一个复选框列表,并希望绑定到我的viewmodel中的单个计算observable.在我的viewmodel中(基于传递给read函数的参数)我想根据某些条件返回true/false.

var myViewModel=function(){
    this.myprop=ko.computed({read: function(){
    //would like to receive an argument here to do my logic and return based on argument.
}
});
};

<input type="checkbox" data-bind="checked: myprop(someval1)" />
<input type="checkbox" data-bind="checked: myprop(someval2)" />
<input type="checkbox" data-bind="checked: myprop(someval3)" />
Run Code Online (Sandbox Code Playgroud)

有什么建议?

Jef*_*ado 84

创建一个函数,其唯一目的是返回计算的observable.它可以根据需要采用参数.如果你想要它是一个双向绑定,它必须是一个单独的计算observable.

然后在绑定中,使用适当的参数调用该函数.它返回的计算的observable将绑定到您的视图中并将照常更新.

这是一个小提琴,我使用这种技术来创建事件处理程序.你可以在这里做类似的事情.

您可以通过将函数作为observable上的方法来保持其清洁.通过添加到ko.observable.fn原型或直接添加到可观察实例.

ko.observable.fn.bit = function (bit) {
    return ko.computed({
        read: function () {
            return !!(this() & bit);
        },
        write: function (checked) {
            if (checked)
                this(this() | bit);
            else
                this(this() & ~bit);
        }
    }, this);
};
// or
function ViewModel() {
    this.flags = ko.observable(0);

    this.flags.bit = function (bit) {
        return ko.computed({
            read: function () {
                return !!(this() & bit);
            },
            write: function (checked) {
                if (checked)
                    this(this() | bit);
                else
                    this(this() & ~bit);
            }
        }, this);
    }.bind(this.flags);
}    
Run Code Online (Sandbox Code Playgroud)

然后申请你的观点

<input type="checkbox" data-bind="checked: flags.bit(0x1)"/>
<input type="checkbox" data-bind="checked: flags.bit(0x2)"/>
<input type="checkbox" data-bind="checked: flags.bit(0x4)"/>
<input type="checkbox" data-bind="checked: flags.bit(0x8)"/>
Run Code Online (Sandbox Code Playgroud)

演示


但是,如果您只是尝试将所有这些复选框绑定到视图模型中的单个值,则无需执行此操作.checked在视图模型中使用数组上的绑定,并为复选框指定值.每个选中的值都将添加到数组中.这将是一种双向约束.

<input type="checkbox" data-bind="checked: checkedValues, value: 1"/>
<input type="checkbox" data-bind="checked: checkedValues, value: 2"/>
<input type="checkbox" data-bind="checked: checkedValues, value: 3"/>
<input type="checkbox" data-bind="checked: checkedValues, value: 4"/>
Run Code Online (Sandbox Code Playgroud)
var viewModel = {
    checkedValues: ko.observableArray([])
};
Run Code Online (Sandbox Code Playgroud)

演示


Isa*_*aac 6

接受的答案是不错的,但是如果你有一个为每个复选框生成一个ko.computed的函数,你会在多个匿名计算的observables中增加不必要的开销,当你的复选框列表超过4-5个选项时,这会快速增加.

这是按位方案的更简单的实现,但计算的函数可以是任何需要的.

<input type="checkbox" data-bind="checked: checkedList, value: 1" />
<label>Value 1</label>
<input type="checkbox" data-bind="checked: checkedList, value: 2" />
<label>Value 2</label>
<input type="checkbox" data-bind="checked: checkedList, value: 4" />
<label>Value 4</label>
<input type="checkbox" data-bind="checked: checkedList, value: 8" />
<label>Value 8</label>
Run Code Online (Sandbox Code Playgroud)

脚本:

var vm = function() {
    var vm = this;

    this.checkedList = ko.observableArray();
    this.bitwiseValue = ko.computed({
        read: function () {
            return vm.checkedList().reduce(function (prev, curr) {
                return prev | curr;
            }, 0);
        },
        write: function (myVal) {
            vm.checkedList.removeAll();
            var placeValue = 1;

            while(myVal > 0) {
                if((myVal % 2) == 1) {
                    alert(placeValue);
                    vm.checkedList.push(placeValue.toString());
                }

                myVal = myVal >>> 1;                    
                placeValue = placeValue * 2;
            }
        }
    }, this);
}

ko.applyBindings(vm);
Run Code Online (Sandbox Code Playgroud)

示例小提琴:http://jsfiddle.net/i_vargas3/RYQgg/