我有一个淘汰赛计算方法类似于检查/取消选中所有但是在字符串上为“是”'并且没有'单选按钮。
我想尝试扩展它,以便它可以对付不同的可观察属性。目前,如果所有' paramOne'来自' optionList'的属性被选为'是'然后我回答“是”',类似于' no'。但是,我也想将它用于“paramTwo”#39;参数和' paramThree'参数等。
任何想法如何做到这一点?也许计算机不适合这里?
在这里小提琴:https://jsfiddle.net/3kpx5qaf/
var AppViewModel = function() {
var self = this;
self.optionList = ko.observableArray();
self.optionList().push({
id : 'option1',
title: "option one",
paramOne:ko.observable(),
paramTwo: ko.observable(),
paramThree: ko.observable(),
paramFour: ko.observable()
});
self.optionList().push({
id : 'option2',
title: "option two",
paramOne:ko.observable(),
paramTwo: ko.observable(),
paramThree: ko.observable(),
paramFour: ko.observable()
});
self.selectAll = ko.computed({
read: function() {
var numNo = 0;
var numYes = 0;
var items = self.optionList();
ko.utils.arrayFirst(items, function(item) {
if(item.paramOne() == "No"){
numNo += 1;
}else if(item.paramOne() == "Yes"){
numYes += 1;
}
});
if(numNo == items.length){
return "No";
}else if(numYes == items.length){
return "Yes";
}else{
return null;
}
},
write: function(value) {
var items = self.optionList();
ko.utils.arrayForEach(items, function(item) {
item.paramOne(value);
});
}
});
}
ko.applyBindings(new AppViewModel());
答案 0 :(得分:1)
您很可能遇到XY问题。您甚至可以通过询问" X在这里不是最合适的方式来提及这一点吗?"。但是,您没有给出任何上下文或真正的示例(我希望您的真实代码没有" ParamOne
"等作为变量?)。因此,提出更好的解决方案非常困难。
您询问目前所处方法的问题可以解释为:
如何干掉
computed
个功能,以便将它们重用于paramTwo
等?
您可以通过提取该位代码来执行 。这是一个简单的例子,只有javascript:
var AppViewModel = function() {
var self = this;
// ...code omitted for brevity...
function getReadFn(propertyName) {
return function() {
var numNo = 0;
var numYes = 0;
var items = self.optionList();
ko.utils.arrayFirst(items, function(item) {
if (item[propertyName]() == "No") { numNo += 1; }
else if (item[propertyName]() == "Yes") { numYes += 1; }
});
if (numNo == items.length) { return "No"; }
else if (numYes == items.length) { return "Yes"; }
else { return null; }
};
}
function getWriteFn(propertyName) {
return function(value) {
var items = self.optionList();
ko.utils.arrayForEach(items, function(item) {
item[propertyName](value);
});
};
}
self.selectAll_paramOne = ko.computed({
read: getReadFn("paramOne"),
write: getWriteFn("paramOne")
});
self.selectAll_paramTwo = ko.computed({
read: getReadFn("paramTwo"),
write: getWriteFn("paramTwo")
});
//etc.
}
或者,您也可以create your own extender封装逻辑。
然而,请再次仔细评估您的方法。具体做法是:
答案 1 :(得分:1)
如果选项的所有参数均为"yes"
或"no"
- 或{{1},我会根据您的问题收集您想要的属性"yes"
或"no"
如果有不匹配的话。
如果缺少更好的名字,请拨打该属性null
。由于它的价值取决于一堆可观测量,因此使用ko.computed来完成这项任务是很自然的。
您的示例应用程序由两部分组成 - overallSelection
,其中包含多个参数,以及Option
,即选项的容器。这是两个视图模型,实现如下(通过单击下面的按钮运行代码):
OptionList

function Option(data) {
var self = this;
self.paramNames = ["paramOne", "paramTwo", "paramThree", "paramFour"];
self.id = data.id;
self.title = data.title;
self.paramNames.forEach(function (paramName) {
self[paramName] = ko.observable();
});
self.overallSelection = ko.pureComputed(function () {
var ref;
self.paramNames.forEach(function (paramName, i) {
if (i === 0) ref = self[paramName]();
else if (ref !== self[paramName]()) ref = null;
});
return ref;
});
}
function OptionList(data) {
var self = this;
self.options = ko.observableArray(data.options.map(function (data) {
return new Option(data);
}));
}
// -------------------------------------------------------------------------
var vm = new OptionList({
options: [
{id: 'option1', title: 'option one'},
{id: 'option2', title: 'option two'}
]
});
ko.applyBindings(vm);

ul {
list-style: none;
padding: 0;
}
.param {
display: inline-block;
width: 6em;
}

注意:
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<ul data-bind="foreach: options">
<li>
<h4 data-bind="text: title"></h4>
<ul data-bind="foreach: paramNames">
<li>
<span data-bind="text: $data" class="param"></span>
<label><input type="radio" value="yes" data-bind="checked: $parent[$data]"> Yes</label>
<label><input type="radio" value="no" data-bind="checked: $parent[$data]"> No</label>
</li>
</ul>
<b class="param">Overall</b> <span data-bind="text: overallSelection"></span>
</li>
</ul>
或"yes"
,但正如评论中所示,我会反对该变体。通过从"no"
属性切换到value
绑定(the docs on the checked
binding的一部分),可以轻松更改为实际布尔值。checkedValue
computed会返回任何值,只要所有相关参数共享它。如果切换到布尔值,则无需更改代码。overallSelection
的等效文件或使用polyfills(我倾向于推荐Sugar.js)。ko.utils
之类的名称提供给那些没有的名称,实际上,&#34;选择所有&#34;。