Knockout.js 从多个DOM元素中设置ko.observable值
假设我有一个问题列表,在一个通过asmx web方法从JSON检索的Knockout.js 从多个DOM元素中设置ko.observable值,knockout.js,Knockout.js,假设我有一个问题列表,在一个通过asmx web方法从JSON检索的ko.mapping构建的模型中有控件类型(即文本框、选择列表、复选框等),我如何根据多个DOM元素设置问题的答案 假设我有以下问题: { text:"This is the question text", answer:null, controlType:"picker" } 然后我创建了一个picker模板,如下所示: <select data-bind
ko.mapping
构建的模型中有控件类型(即文本框、选择列表、复选框等),我如何根据多个DOM元素设置问题的答案
假设我有以下问题:
{
text:"This is the question text",
answer:null,
controlType:"picker"
}
然后我创建了一个picker
模板,如下所示:
<select data-bind="options: ['Large','Medium','Small'], optionsCaption: 'Select size...'" />
<select data-bind="options: ['Black','Red','Green'], optionsCaption: 'Select colour...'" />
<select data-bind="computedAnswer: $data, options: ['Large','Medium','Small'], optionsCaption: 'Select size...'" />
<select data-bind="computedAnswer: $data, options: ['Black','Red','Green'], optionsCaption: 'Select colour...'" />
这将为我从元素中选择[Large]和[Red]
这是我到目前为止试过的
在我的可观察对象上设置一个ko.computed
编辑:这里有一个想法
我在视图模型中循环了问题,并在每个问题上设置了一个ko.computed
,通过ID访问DOM,因此我的模板变成:
<select data-bind="attr: { 'id':'leftOption' }, options: ['Large','Medium','Small'], optionsCaption: 'Select size...'" />
<select data-bind="attr: { 'id':'rightOption' }, options: ['Black','Red','Green'], optionsCaption: 'Select colour...'" />
question.computedAnswer = ko.computed({
read: function () {
return question.answer();
},
write: function (value) {
var left = $('#leftOption').val();
var right = $('#rightOption').val();
question.answer(left + ' ' + right);
}
});
这只会尖叫哦,上帝,求你了,不要对我大吼大叫,因为我访问DOM的方式非常混乱(最近我学到了一个不这样访问DOM的好方法,感觉很不对劲!!)
创建自定义绑定处理程序
警告:我仍在处理自定义处理程序
为了通过绑定处理程序限制对DOM的访问,我为此创建了一个绑定处理程序。。。但似乎无法让它工作。这个想法是在,但它不工作,因为它没有做任何事情
基本上,我正在处理程序中尝试这样做:
ko.bindingHandlers.computedAnswer = {
update: function (element, value, all, model, context) {
switch (model.controlType()) {
case 'picker': {
var $parent = $(element).parent();
var first = $parent.find('select:first').val();
var second = $parent.find('select:last').val();
if (first && second) {
model.answer(first + ' ' + second);
} else {
model.answer(null);
}
}
}
}
};
并尝试在我的模板上激活此项,如下所示:
<select data-bind="options: ['Large','Medium','Small'], optionsCaption: 'Select size...'" />
<select data-bind="options: ['Black','Red','Green'], optionsCaption: 'Select colour...'" />
<select data-bind="computedAnswer: $data, options: ['Large','Medium','Small'], optionsCaption: 'Select size...'" />
<select data-bind="computedAnswer: $data, options: ['Black','Red','Green'], optionsCaption: 'Select colour...'" />
有人知道如何让它工作吗?视图是存储数据的错误位置。它也不是很灵活。如果你的
选取者问题存储了他们自己的选项怎么办?这不仅允许每个问题有不同的选项,而且允许有不同数量的选项
它还保留了视图的数据,简化了HTML和viewmodel代码,并且在不需要自定义绑定的情况下将DOM访问排除在viewmodel之外(并不是说您应该不惜一切代价避免自定义绑定,我只是认为这不是一个好的例子)
问题选取者
问题
}, {
text: "dependent on master question",
answer: null,
controlType: "picker",
pickers: [
{ name: "Size", options: ['Large', 'Medium', 'Small'], value: '' },
{ name: "Color", options: ['Red', 'Blue', 'Green'], value: '' }
]
}
查看
<script type="text/html" id="picker">
<!-- ko foreach: pickers -->
<label data-bind="text: name"></label>
<select data-bind="options: options, value: value, optionsCaption: 'Choose...'"></select>
<!-- /ko -->
</script>
你的问题值得更多的投票。您总是有多个小提琴,显示问题和您认为应该采取的路径,您根据您遇到的具体问题定制它们(即使您过去的问题表明整个问题有更多的部分),您在问题中包含代码,并清楚地展示您的努力。@Tyrsius我很感激。我觉得这只是一种普通的礼貌,如果有人打算自己抽出时间来帮助你,那么你应该帮助自己才是公平的!这是一种礼貌,但肯定不常见。有趣的是,我从未想过在提问时会有一系列的挑选者。。。但是,如果我无法控制返回给我的JSON,并且我必须在模板中指定SELECT元素的数量,那该怎么办?嗯,我想我可以在使用pickers数组解析JSON之后扩展可观察的元素?我想这就是我要走的路,除非我(或其他人)想出一个更好的方法。如果你没有控制权,我会在解析它们之后扩展它们。因为无论哪种方式,viewmodel都应该表示数据,而不是视图。如果选项真的是静态的,你可以把它们放在根视图模型上,而不是每个问题上。很抱歉,最近接受了,对我的问题做了一些整理。