我想知道是否有可能与knockoutjs到绑定时传递参数。
我绑定的复选框的列表,并希望绑定到单个计算观察到的在我的视图模型。 在我的视图模型(基于传递给读取功能参数)我想根据一定的条件下,返回真/假。
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)" />
有什么建议?
创建其唯一的目的是返回一个计算观察到的一个功能。 这可能需要在参数你想要的。 它必须是一个单独的计算观察到的,如果你希望它是一个双向绑定。
然后,在你的绑定,调用适当的参数该功能。 该计算观察到它返回你的观点将被绑定到和将更新如常。
这里有一个小提琴 ,我用这个技术来创建事件处理程序。 你可以做同样的事情在这里。
您可以通过功能上可观察的方法保持它的清洁。 无论是通过向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);
}
然后应用到你的观点
<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)"/>
演示
然而,如果你只是想绑定所有复选框在您的视图模型中的单个值,你不需要做。 使用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"/>
var viewModel = {
checkedValues: ko.observableArray([])
};
演示
接受的答案是体面的,但如果你有生成ko.computed每个复选框的功能,你正在使用多个匿名计算的观测,当你的复选框列出超过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>
脚本:
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);
例如拨弄这里: http://jsfiddle.net/i_vargas3/RYQgg/
没有理由使用一个computed
值。 只需在您的视图模型定义函数,然后绑定checked
它。
下面是一个非常简单的例子。
-
HTML
<input type="checkbox" data-bind="checked: isEven(1)" />
<input type="checkbox" data-bind="checked: isEven(2)" />
<input type="checkbox" data-bind="checked: isEven(3)" />
JS
var MyViewModel=function(){
this.isEven = function(num) {
return (num % 2) == 0;
};
};
ko.applyBindings(new MyViewModel());
-
话虽这么说,这是一个好主意,试图尽可能多的逻辑推到您的视图模型的可能。 这将是最好创建一个模型的复选框作为一个对象,然后逻辑,这就是如果复选框应检查可以封装内部视图模型。
-
编辑:根据要求做双向绑定我写一个扩展来管理可观察到的。
http://jsfiddle.net/jearles/j6zLW/5/
ko.extenders.bitwise = function(target, bitCount) {
target.bits = [];
target.checked = ko.observableArray();
// Create bit array based on requested number of bits
for (i=bitCount-1; i>=0; i--) {
target.bits.push(''+Math.pow(2, i));
}
// Define a function to create bits
function makeBits(newValue) {
var num = !isNaN(newValue) ? parseInt(newValue) : 0;
var arr = [];
for (i=0; i<target.bits.length; i++) {
var bitValue = parseInt(target.bits[i]);
if ((num & bitValue) == bitValue) arr.push(target.bits[i]);
}
target.checked(arr);
}
// Define a function to combine bits
function makeBitwise(newBits) {
var num = 0;
for (i=0; i<target.bits.length; i++) {
if (newBits.indexOf(target.bits[i]) > -1) num += parseInt(target.bits[i]);
}
target(num);
}
// Create initial bits
makeBits(target());
// Make bits whenever the value changes
target.subscribe(makeBits);
// Make number whenever the bits change
target.checked.subscribe(makeBitwise);
// Return the original observable
return target;
};
var MyViewModel=function(){
var self = this;
this.number = ko.observable(2).extend({ bitwise: 8});
};
ko.applyBindings(new MyViewModel());
如果不知道的细节,好像你应该做的是定义一个ko.observableArray或计算阵列值是什么
HTML:
myprop: <input data-bind="value: myprop">
<div data-bind="foreach: selections">
<label>
<span data-bind="text: value"></span>
<input type="checkbox" data-bind="checked: selected"/>
</label>
</div>
JS:
$(function() {
function Model() {
this.self = this
self.myprop = ko.observable(14)
self.bits = [1, 2, 4, 8, 16, 32, 64, 128]
self.selections = ko.computed(function() {
return self.bits.map(function(bit) {
console.log(myprop() & bit)
return {
value: bit,
selected: (myprop() & bit) == bit
}
})
})
}
ko.applyBindings(new Model())
})
而不是从标记传递值来定义模型状态