2014-05-01 2 views
1

KnockOut.js를 사용하여 뷰에 복잡한 객체를 바인딩하려고합니다. overservable() 및 observableArray()를 사용하지 않고 객체를 뷰와 바인딩 할 수있었습니다. 그러나 observable() 구현할 때 반환 된 결과를 내 javascript viewmodel에서 관찰 가능한 개체를 추가하고 내보기 viewmodel 바인딩 할 수 없습니다.Knockout.js에서 복잡한 객체로 뷰를 바인딩 할 수 없습니다.

 

    Model: 

    public class SurveyQuestion 
    { 
     public string QuestionNumber { get; set; } 
     public string Question { get; set; } 
     public QuestionType QuestionTypeStructure { get; set; } 
     public IList OptionsList { get; set; } 
    } 

    public enum QuestionType 
    { 
     CheckBox, 
     RadioButton, 
     TextBox, 
     AdvancedCheckBox, 
     AdvancedRadioButton 
    } 

    public class Options 
    { 
     public string OptionValue { get; set; } 
    } 

    ViewModel: 

    public class SurveyCollection 
    { 
     public IList SurveyList { get; set; } 
    } 

json으로 위의 일반적인 결과의 결과

 

    @model Test.UI.ViewModel.SurveyCollection 
    @using System.Web.Script.Serialization 

    [h2]Survey[/h2] 

    [div data-bind="template: { name: 'surveyTemplate', foreach: SurveyList }"][/div] 

    [script type="text/html" id="surveyTemplate"] 
     [div style = "margin-bottom:20px"] 
      [div style = "margin-bottom:10px"] 
       [strong data-bind="text: Question"][/strong] 
      [/div] 
      [div] 
[ul data-bind="template: { name: function() { return QuestionTypeStructure.toString(); }, foreach: OptionsList }"] 
       [ul] 
      [/div] 
     [/div] 
    [/script] 

    [script type="text/html" id="0"] 
     [div] 
      [input type = "radio" style = "margin-right:10px; width: auto"/][span data-bind="text: $data.OptionValue" /] 
     [/div] 
    [/script] 

    [script type="text/html" id="1"] 
     [div] 
      [input type = "checkbox" style = "margin-right:10px"/][span data-bind="text: $data.OptionValue" /] 
     [/div] 
    [/script] 

    [script type="text/html" id="2"] 
     [div] 
      [input type = "text" style = "margin-right:10px"/] 
      [span data-bind="value: $data.OptionValue" /] 
     [/div] 
    [/script] 


     $(document).ready(function() { 
      var surveyViewModel = { 
       SurveyList: ko.observableArray([]) 
      }; 

      var data = $('').html("@(new JavaScriptSerializer().Serialize(Model))").text(); 
      var jsonData = $.parseJSON(data); 
      if (jsonData != undefined) { 
       //$.each(jsonData.SurveyList, function (baseIndex, T) { 
       ko.utils.arrayForEach(jsonData.SurveyList, function (T) { 
        var surveyModel = new SurveyModel(T); 
        surveyViewModel.SurveyList.push(surveyModel); 

        ko.utils.arrayForEach(T.OptionsList, function (Q) { 
         var optionModel = new OptionModel(Q); 
         surveyModel.OptionsList.push(optionModel); 
         //surveyViewModel.SurveyList[baseIndex].OptionsList.push(optionModel); 
        }); 
       }); 
       ko.applyBindings(surveyViewModel); 
      } 
    }); 

    function SurveyModel(T) 
    { 
     this.QuestionNumber = ko.observable(T.QuestionNumber); 
     this.Question = ko.observable(T.Question); 
     this.QuestionTypeStructure = ko.observable(T.QuestionTypeStructure); 
     this.OptionsList = ko.observableArray([]); 
    } 

    function OptionModel(Q) 
    { 
     this.OptionValue = ko.observable(Q.OptionValue); 
    } 

 

    {"SurveyList":[ 

    {"QuestionNumber":"1","Question":"Write down the second consonant after the second vowel?","QuestionTypeStructure":2,"OptionsList":[{"OptionValue":"F"},{"OptionValue":"G"},{"OptionValue":"C"},{"OptionValue":"B"}]}, 

    {"QuestionNumber":"2","Question":"Complete the following letter series: ZYX/ VW/ UTS/ QR/ PON/ LM/ KJI?","QuestionTypeStructure":1,"OptionsList":[{"OptionValue":"GB"},{"OptionValue":"IJ"},{"OptionValue":"GH"},{"OptionValue":"LM"}]}, 

    {"QuestionNumber":"3","Question":"What would be the numrical digits to represent the word VOWEL when the letters of the alphabets were numbered as A 26, B 25, C 24 and o on till Z 1.","QuestionTypeStructure":0,"OptionsList":[{"OptionValue":"5 ,12 ,4, 22, 15"},{"OptionValue":"6 ,12 ,5, 22, 15"},{"OptionValue":"5 ,14 ,4, 22, 16"},{"OptionValue":"4 ,13,4, 22, 12"}]} 

    ]} 

아래 내가 뭔가 다른 HTML을 돌려 사과 :

다음은 서버 측의 코드 구현입니다.

[ul data-bind="template: { foreach: OptionsList }"] 당신이 템플릿 이름을 지정하지 않을
 

    Error: Cannot find template with ID function observable() { 
      if (arguments.length > 0) { 
       // Write 

       // Ignore writes if the value hasn't changed 
       if ((!observable['equalityComparer']) || !observable['equalityComparer'](_latestValue, arguments[0])) { 
        observable.valueWillMutate(); 
        _latestValue = arguments[0]; 
        if (DEBUG) observable._latestValue = _latestValue; 
        observable.valueHasMutated(); 
       } 
       return this; // Permits chained assignments 
      } 
      else { 
       // Read 
       ko.dependencyDetection.registerDependency(observable); // The caller only needs to be notified of changes if they did a "read" operation 
       return _latestValue; 
      } 
     } 
    http://localhost:3391/Scripts/knockout-2.1.0.debug.js 
    Line 2653 

답변

0

문제가 : 문제는 위의 결과로 모질라의 오류 필드에 밝혀입니다. 당신이 생각하는 다른 템플릿을 판단하면 다음과 같을 것입니다.

[ul data-bind="foreach: OptionsList "] 
    [li data-bind="template: $data.OptionValue] 
    [/li] 
[/ul] 
+0

@Deepak Nair, @Deepak Nair, 답을 편집하지 말고 대신 주석을 추가하십시오. 즉, 대답은 여전히 ​​내 생각에 동일합니다. surveyTemplate은 아직 어떤 템플릿을 사용할 지에 대한 이름이 부족합니다. '[ul data-bind = "template : {foreach : OptionsList}"] –

+0

안녕하세요, 유감스럽게도 댓글을 읽지 않아 죄송합니다. 질문을 수정했습니다. 템플릿을 추가했지만 객체 "QuestionTypeStructure"가 viewmodel 객체에서 발견되지 않았습니다. 그것없이 실행하려 할 때 코드는 템플릿을 표시하지 않고 작동했습니다. –

+0

'QuestionTypeStructure'가 관찰 가능으로 정의되었으므로'name : function() {return QuestionTypeStructure(). toString();}'대신 –