Nested knockout template binding

2019-09-21 10:04发布

问题:

     $.ajax({
                    url: "/survey/surveyQuestions",
                    success: function (questionsData) {
                        $.ajax({
                            url: "/survey/surveyOptions",
                            success: function (optionsData) {
                                alert(questionsData.length);
                                for (var i = 0; i < questionsData.length; i++) {
                                    QuestionsScript.Question = ko.mapping.fromJS(questionsData[i]); 
                                    ko.applyBindings(QuestionsScript, document.getElementById("innerDiv")); 
                                    for (var j = 0; j < optionsData.length; j++) { 
                                               if (optionsData[j].QuestionId = questionsData.QuestionId[i]) {
                                                     OptionsScript.Option = ko.mapping.fromJS(optionsData[j]);
                                                     ko.applyBindings(OptionsScript, document.getElementById(" ... here i nee to give options template table Id....."));
                                                  }
                                        }
                                }


                            }
                        });

                    }
                });

I need to bind like below

Question 1
       Option1
       Option2
       Option3
Question 2
       Option1
       Option2
       Option3
Question 3
        Option2
        Option3

My Templates are

<script id="QuestionsScript" type="text/x-jquery-tmpl">
<div data-bind="attr:{id :QuestionId}"  class="question">
    <h2><label data-bind="text :QuestionText" /></h2>
    <div class="option">
        <table data-bind="attr:{id : QuestionId} , template: {name:'OptionsScript', foreach: Option}">
            <tbody>
            </tbody>
        </table>
    </div>
</div>
</script>
<script id="OptionsScript" type="text/x-jquery-tmpl">
<tr>
    <td>{{= OptionText}}</td>
</tr>
</script>

As I have stated about my desired output and template,I am not aware why I can't get that. so Kindly provide me with any sample code for this. Thanks in advance.

回答1:

I think you can do this like that:

function Question(id, name) {
    this.id = id;
    this.name = name;
    this.answers = ko.observableArray();
}

function Answer(id, name) {
    this.id = id;
    this.name = name;
}

function ViewModel() {
    this.questions = ko.observableArray();
    var self = this;

    //dummy data
    self.init = function () {
        var q1 = new Question(1, "Question 1");
        var q1a1 = new Answer(1, "Option 1");
        var q1a2 = new Answer(2, "Option 2");
        q1.answers([q1a1, q1a2]);

        var q2 = new Question(2, "Question 2");
        var q2a1 = new Answer(1, "Option 1");
        var q2a2 = new Answer(2, "Option 2");
        var q2a3 = new Answer(3, "Option 3");
        q2.answers([q2a1, q2a2, q2a3]);

        var q3 = new Question(3, "Question 3");
        var q3a1 = new Answer(1, "Option 1");
        var q3a2 = new Answer(2, "Option 2");
        var q3a3 = new Answer(3, "Option 3");
        q3.answers([q3a1, q3a2, q3a3]);

        self.questions([q1, q2, q3]);
    };

    self.init();
}

And bind view model like that:

<div data-bind="foreach:questions">
    <div data-bind="attr:{id :id}" class="question">
        <h2><label data-bind="text :name" /></h2>
        <div class="option">
            <table data-bind="attr:{id : id}">
                <tbody data-bind="foreach:answers">
                    <tr>
                        <td data-bind="text:name"></td>
                    </tr>
                </tbody>
            </table>
        </div>
    </div>
</div>

Here is fiddle with example.