我成功地将分层JSON数据绑定到我的视图。但是,一旦我使用knockout.mapping将相同的JSON数据投影到视图模型中,foreach函数就不会遍历子数组。
绑定到viewModel数据时,我知道子数据(Answers)存在,因为我可以使用
显示对象引用观点:
<div data-bind="foreach: $data">
<p data-bind="html: QuestionText">
<!-- this section outputs [object Object] when bound to pageViewModel or Json -->
<p data-bind="html: Answers">
<!-- RadioButtonSelection-->
<div data-bind="if: QuestionSelectionMode == 'RadioButtonSelection'">
<span data-bind="foreach: $data.Answers">
<input type="radio" data-bind="attr: {name: $parent.QuestionId}, value: AnswerId" /><span data-bind="text: AnswerText"></span>
</span>
</div>
<!-- CheckBoxSelection-->
<div data-bind="if: QuestionSelectionMode == 'CheckBoxSelection'">
<span data-bind="foreach: $data.Answers">
<div><input type="checkbox" data-bind="value: AnswerId"/><span data-bind="text: AnswerText"></span></div>
</span>
</div>
<!-- DropDownListSelection-->
<div data-bind="if: QuestionSelectionMode == 'DropDownListSelection'">
<select data-bind="options: $data.Answers, optionsText: 'AnswerText', optionsValue: 'AnswerId'"></select>
</div>
</p>
</div>
ViewModel代码:
<script type="text/javascript">
/* get the first page of questions and bind them */
@{
string startUrl = "URL-Removed" + ViewData["formId"] + "?page=" + ViewData["pageNumber"];
}
var pageViewModel;
$.ajax({ url: '@startUrl' ,
async: false,
dataType: 'json',
success: function (data) {
//console.log("JSON received: " + JSON.stringify(data));
// when i bind to the view model the parent question text shows, but not the child answers
pageViewModel = ko.mapping.fromJS(data);
ko.applyBindings(pageViewModel);
//ko.applyBindings(data);
},
error: function (jqXHR, textStatus, errorThrown) {
console.log("Error: TextStatus: " + textStatus + " errorThrown: " + errorThrown);
}
});
</script>
以下是JSON中的一些数据:
[{"FormId":0,"QuestionId":28807,"QuestionSelectionMode":"StaticTextSelection","QuestionText":"<hr />\r\n<div><span style=\"font-size: medium\"><span style=\"color: #003366\"><strong>Event Details</strong></span></span></div>","DisplayOrder":1,"PageNumber":1,"Answers":[]},{"FormId":0,"QuestionId":28782,"QuestionSelectionMode":"RadioButtonSelection","QuestionText":"<div><span style=\"font-size: larger\"><strong>What type of patient safety event is being reported?</strong></span><span style=\"font-size: x-small\"><strong> </strong><font color=\"#ff0000\" size=\"1\">(Required)</font></span></div>","DisplayOrder":2,"PageNumber":1,"Answers":[{"AnswerId":460935,"QuestionId":0,"AnswerTypeId":null,"RegularExpressionId":null,"AnswerText":"Reached the patient","DisplayOrder":1,"Selected":null,"DefaultText":null,"Mandatory":null,"ValidatorId":null,"SyncRefMandatory":null,"FieldLength":null,"AnswerFormId":null,"EntryMaskId":null,"ShowTimeSelector":null,"Disabled":false},{"AnswerId":460936,"QuestionId":0,"AnswerTypeId":null,"RegularExpressionId":null,"AnswerText":"Did not reach the patient (Near Miss)","DisplayOrder":2,"Selected":null,"DefaultText":null,"Mandatory":null,"ValidatorId":null,"SyncRefMandatory":null,"FieldLength":null,"AnswerFormId":null,"EntryMaskId":null,"ShowTimeSelector":null,"Disabled":false},{"AnswerId":460937,"QuestionId":0,"AnswerTypeId":null,"RegularExpressionId":null,"AnswerText":"Unsafe Condition","DisplayOrder":3,"Selected":null,"DefaultText":null,"Mandatory":null,"ValidatorId":null,"SyncRefMandatory":null,"FieldLength":null,"AnswerFormId":null,"EntryMaskId":null,"ShowTimeSelector":null,"Disabled":false}]},{"FormId":0,"QuestionId":46080,"QuestionSelectionMode":"RadioButtonSelection","QuestionText":"<div><span style=\"font-size: larger\"><strong>Was the patient harmed?</strong></span></div>","DisplayOrder":3,"PageNumber":1,"Answers":[{"AnswerId":632595,"QuestionId":0,"AnswerTypeId":null,"RegularExpressionId":null,"AnswerText":"Yes","DisplayOrder":1,"Selected":null,"DefaultText":null,"Mandatory":null,"ValidatorId":null,"SyncRefMandatory":null,"FieldLength":null,"AnswerFormId":null,"EntryMaskId":null,"ShowTimeSelector":null,"Disabled":false},{"AnswerId":632596,"QuestionId":0,"AnswerTypeId":null,"RegularExpressionId":null,"AnswerText":"No","DisplayOrder":2,"Selected":null,"DefaultText":null,"Mandatory":null,"ValidatorId":null,"SyncRefMandatory":null,"FieldLength":null,"AnswerFormId":null,"EntryMaskId":null,"ShowTimeSelector":null,"Disabled":false}]}, and so on...
有什么想法吗?
答案 0 :(得分:1)
在if绑定中,您将放入一个完整的语句,而不仅仅是引用viewmodel上的属性。因此,您需要调用observable(作为函数)而不是仅仅引用它。翻译:而不是
<div data-bind="if: QuestionSelectionMode == 'CheckBoxSelection'">
你应该
<div data-bind="if: QuestionSelectionMode() == 'CheckBoxSelection'">
所以这是更新的标记:
<div data-bind="foreach: $data">
<p data-bind="html: QuestionText">
<!-- RadioButtonSelection-->
<div data-bind="if: QuestionSelectionMode() == 'RadioButtonSelection'">
<span data-bind="foreach: Answers">
<input type="radio" data-bind="attr: {name: $parent.QuestionId}, value: AnswerId" /><span data-bind="text: AnswerText"></span>
</span>
</div>
<!-- CheckBoxSelection-->
<div data-bind="if: QuestionSelectionMode() == 'CheckBoxSelection'">
<span data-bind="foreach: Answers">
<div><input type="checkbox" data-bind="value: AnswerId"/><span data-bind="text: AnswerText"></span></div>
</span>
</div>
<!-- DropDownListSelection-->
<div data-bind="if: QuestionSelectionMode() == 'DropDownListSelection'">
<select data-bind="options: Answers, optionsText: 'AnswerText', optionsValue: 'AnswerId'"></select>
</div>
</div>
这是一个工作小提琴:http://jsfiddle.net/g5g36/
其他几点说明:
您正试图在p标签上执行'html:answers'绑定。 html绑定旨在告诉您,您的viewmodel上有一个HTML字符串,您希望将其放入现有标记内。但是,然后在p标签内定义各种其他标记。完全摆脱这个标签。
我必须更正JSON,以便您使用双斜杠而不是单斜线(请参阅小提琴)以使JSON解析器满意。根据您的服务处理方式,这可能与您无关。
$ data隐含在绑定中,因此您可以绑定到'Answers'而不是绑定到'$ data.Answers'。无论哪种方式都有效,但删除$ data会使其更清晰。
从技术上讲,你不应该在p标签内加上div标签。
p标签应该关闭