在淘汰赛中动态渲染控件并绑定它们?

时间:2017-03-01 22:20:10

标签: javascript knockout.js

我有一个通过对我的knockout viewmodel的ajax调用提供的JSON有效负载。有效载荷的结构类似于:

{  
   "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"
                  }
               ]
            }
         ]
      }
   ]
}

在我的模板内部,我有一个ForEach循环遍历所有类别,然后是第二个ForEach循环,它遍历该类别的所有问题。我需要根据" controlType"动态创建输入,选择和textareas。每个问题,然后将它们绑定到一个observableArray,其结构类似于:

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

我创建了一个可以在foreach中动态呈现html的函数,但我不知道如何完成剩下的工作。

这是一个演示模板:

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

如何绑定和存储这些输入的结果?

1 个答案:

答案 0 :(得分:1)

我认为在这里使用templatesif binding会很明智。

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

你可以像这样定义模板:

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

至于存储答案,为什么不在问题中添加selectedAnswer

{  
   "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
            }
         ]
      }
   ]
}

另一个解决方案是提供一系列答案和问题ID:

{  
   "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"
                  }
               ]
            }
         ]
      }
   ]
}