示例 jsFiddle
这是我的 JSON 形式的模型结构的概述
var json = JSON.stringify([{
text: 'Enter your name',
controlType: 'TextBox',
answer: null
}, {
text: 'Choose some of these',
controlType: 'Label',
answer: null
}, {
text: 'Item one',
controlType: 'CheckBox',
answer: null
}, {
text: 'Item two',
controlType: 'CheckBox',
answer: null
}, {
text: 'Item three',
controlType: 'CheckBox',
answer: null
}, {
text: 'Choose from multiple elements',
controlType: 'Multiple',
answer: null
}, ]);
我有一个问题列表(上面详述),每个问题都有其各自text
的controlType
属性。我创建了一个自定义绑定处理程序来在表单上绘制输入,并创建另一个处理程序来处理answer
基于所创建控件的 DOM 结构的处理程序。
例如,对于一个特定的控件类型,我将Multiple作为一种类型,它将创建以下标记:
<select data-bind="options: ['Jan','Feb','Mar'...], optionsCaption: ' - '"></select>
<input type="text" size="5" />
这基本上允许用户在2013 年 1 月提交单个问题的答案,但我正在努力让绑定处理程序工作。
当我第一次开始这样做时,我使用计算的 observables 扩展了每个问题 - 所以在这种情况下,我将question
使用以下计算扩展:
question.answer.month = ko.computed({
read: function () {
if (this.answer()) {
return this.answer().split(' ')[0]; // returns the month part
}
return null;
},
write: function (value) {
if (value) {
this.answer(value);
}
},
owner: question
});
但是我开始陷入各种循环引用地狱——所以我想我应该把它提升一个层次,然后answer
从 DOM 元素中设置我的 observable。
有没有人有任何想法/提示来实现这个工作?
更多信息
看来我之前解释的不够好,所以我会努力一点。
我的每个question
对象都有一个名为controlType
. 这表示应该在页面上绘制哪些 DOM 元素。因此,对于多个(例如)我应该有以下 DOM 元素:
<div class="question">
<label class="question-label" data-bind="text: $data.text"></label>
<select data-bind="value: $data.answer.month, options: [month names]"></select>
<input type="text" data-bind="value: $data.answer.year" />
</div>
这将让用户回答一个问题 - 假设问题文本可能类似于您何时出生?然后上面的 DOM 结构允许他们提交月份和年份的答案,即Jan 1990。现在,在后台我需要从这两个 DOM 元素中获取值并将它们合并为一个单一的答案来设置question.answer
属性。我尝试使用两个计算的可观察对象question.answer.month
,question.answer.year
但是随着我的控制类型变得更加复杂,我进入循环引用地狱,即我的答案取决于它的对应部分,而每一个对应部分都依赖于解析的答案。
简而言之 - 我试图根据未指定数量的 DOM 元素设置可观察的值,在这种(最简单的)情况下,它是一个SELECT
和一个INPUT
元素。