2017-03-01 2 views
0

Ich habe eine JSON-Payload, die von einem Ajax-Aufruf an mein Knockout-Viewmodel übergeben wird. Die Struktur der Nutzlast ist ähnlich:Dynamisch Rendering-Steuerelemente und Bindung an sie in Knockout?

{ 
    "categories":[ 
     { 
     "name":"Category 1", 
     "questions":[ 
      { 
       "id": 1, 
       "questionText":"Question?", 
       "controlType":"text" 
      }, 
      { 
       "id": 2, 
       "questionText":"Question?", 
       "controlType":"radiobutton", 
       "possibleAnswers":[ 
        { 
        "answerId":1, 
        "text":"Yes" 
        }, 
        { 
        "answerId":2, 
        "text":"No" 
        } 
       ] 
      } 
     ] 
     } 
    ] 
} 

Innerhalb von meiner Vorlage ich eine foreach-Schleife, die alle Kategorien iteriert, und dann eine zweite foreach-Schleife, dass iteriert über alle Fragen zu dieser Kategorie. Ich um dynamisch Eingänge wählen zu erstellen, und basierend auf den Textbereiche „control“ jede Frage, und dann binden diese an eine observableArray mit einer Struktur ähnlich:

[ 
    { 
     "questionId":1, 
     "answerId":1 
    } 
] 

Ich habe eine Funktion, die dynamisch Rendern Sie den HTML-Code innerhalb der Foreach, aber ich bin mir nicht sicher, wie ich den Rest erledigen soll.

Hier ist eine Demo-Vorlage:

<div data-bind="foreach:categories"> 
    <h2 data-bind="text:name"></h2> 
    <div data-bind="foreach:questions"> 
     <span data-bind="text:questionText"></span> 
     <div data-bind="html:$parents[0].createControl($data)"></div> 
    </div> 
</div> 

Wie würde ich binden und die Ergebnisse von diesen Eingängen?

Antwort

1

Ich denke mit templates zusammen mit if binding wäre hier klug.

<div data-bind="foreach:categories"> 
    <h2 data-bind="text:name"></h2> 
    <div data-bind="foreach:questions"> 
     <span data-bind="text:questionText"></span> 
     <!-- ko if: controlType() == "radiobutton" --> 
      <div data-bind="template: { name: 'radio-template', data: $data }"></div> 
     <!-- /ko --> 
     <!-- ko if: controlType() == "other-type" --> 
      <div data-bind="template: { name: 'other-type-template', data: $data }"></div> 
     <!-- /ko --> 
     <!-- ... --> 
    </div> 
</div> 

Sie könnten Vorlagen wie folgt definieren:

<script type="text/html" id="radio-template"> 
    <h3 data-bind="text: questionText"></h3> 
    <div data-bind="foreach:possibleAnswers"> 
     <!-- you html here --> 
    </div> 
</script> 

Wie für die Antworten zu speichern, warum nicht ein selectedAnswer auf die Fragen hinzufügen?

{ 
    "categories":[ 
     { 
     "name":"Category 1", 
     "questions":[ 
      { 
       "id": 1, 
       "questionText":"Question?", 
       "controlType":"text" 
      }, 
      { 
       "id": 2, 
       "questionText":"Question?", 
       "controlType":"radiobutton", 
       "possibleAnswers":[ 
        { 
        "answerId":1, 
        "text":"Yes" 
        }, 
        { 
        "answerId":2, 
        "text":"No" 
        } 
       ], 
       "selectedAnswer": -1 
      } 
     ] 
     } 
    ] 
} 

Eine andere Lösung ist eine Reihe von Antworten zu haben und ids Frage:

{ 
    "categories":[ 
     { 
     "answers": [ "questionId": 1, "answer": { "id": -1, "value": "" } ] 
     "name":"Category 1", 
     "questions":[ 
      { 
       "id": 1, 
       "questionText":"Question?", 
       "controlType":"text" 
      }, 
      { 
       "id": 2, 
       "questionText":"Question?", 
       "controlType":"radiobutton", 
       "possibleAnswers":[ 
        { 
        "answerId":1, 
        "text":"Yes" 
        }, 
        { 
        "answerId":2, 
        "text":"No" 
        } 
       ] 
      } 
     ] 
     } 
    ] 
} 
Verwandte Themen