2012-12-17 74 views
0

我已成功將分層JSON數據綁定到我的視圖。但是,一旦我使用knockout.mapping將相同的JSON數據投影到視圖模型中,foreach函數就不會遍歷子數組。Foreach適用於JSON兒童,但不適用於ViewModel

當綁定到視圖模型的數據,我知道孩子的數據(答案)是存在的,因爲我可以用

的意見顯示對象的引用:

<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> 

視圖模型代碼:

<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>&nbsp; </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

是什麼數據是什麼樣子? – CodeThug

+0

以下是部分數據轉儲: – Jelling

回答

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/

一對夫婦的其他說明:

  1. 您正在嘗試在p標記上執行'html:answers'綁定。 html綁定的目的是爲了告訴你在你的viewmodel上有一個HTML字符串,你想要在一個現有的標籤中使用。但是,您可以在p標籤內定義其他所有標記。只需徹底擺脫這個標籤。

  2. 我不得不糾正JSON,以便讓雙倍斜槓而不是單斜槓(請參閱小提琴)使JSON解析器高興。這可能與您無關,具體取決於您的服務如何處理事情。

  3. $ data在綁定中是隱含的,所以不是綁定到'$ data.Answers',而是可以綁定到'Answers'。無論哪種方式工作,但刪除$數據使其更清潔。

  4. 你在技術上不應該在p標籤內部有div標籤。

  5. 的p標籤都應該被關閉

+0

感謝CodeThug。我是否有權假定映射庫默認將所有屬性轉換爲可觀察對象?保持暴力'。 – Jelling

+0

這是正確的。從http://knockoutjs.com/documentation/plugins-mapping.html的文檔中,所有的屬性都被轉換爲可觀察對象,並且所有的數組都被轉換爲可觀察數組。 – CodeThug

相關問題