如何将动态问题集合与动态答案集合绑定到视图模型?

How can I bind a dynamic collection of questions with a dynamic collection of answers to a view model?

我有一个应用是多项选择调查。问题是从数据库中加载的,答案选项也是从数据库中加载的。我想将响应绑定到模型,但我不确定如何实现。这是我的 ViewModel 和视图:

视图模型:

 public class SurveyViewModel : SurveyViewModelBase
     {
         public IEnumerable<SectionViewModel> Sections { get; set; }
         public DemographicQuestionsModel DemographicQuestions { get; set; }
         public string Title { get; set; }
     }
 public class SectionViewModel
     {
        public string SectionTitle { get; set; }
        public IEnumerable<QuestionAnswerViewModel> QAs { get; set; }
     }
 public class QuestionAnswerViewModel
     {
         public QuestionViewModel Question { get; set; }
         public AnswerViewModel SelectedAnswer { get; set; }
         public IEnumerable<QuestionAnswerViewModel> ChildQuestions { get; set; }
     }
 public class QuestionViewModel
     {
         public Guid Id { get; set; }
         public string Text { get; set; }
         public IEnumerable<AnswerViewModel> PossibleAnswers { get; set; }
         public int QuestionNumber { get; set; }
     }
  public class AnswerViewModel
     {
         public Guid Id { get; set; }
         public string AnswerText { get; set; }
     }

查看:

 @using VSC.ViewModels
 @model VSC.ViewModels.SurveyViewModel
 @{
     SectionViewModel section = Model.Sections.FirstOrDefault();
 }
 <div class="row">
     <div class="sectionTitle">@(section.SectionTitle)</div>
 </div>
 <form action="/VSC/Survey">
     @foreach (var qa in section.QAs)
     {
         if (qa.Question.QuestionNumber == 0)
         {
             <div class="row question">
                 @qa.Question.Text
             </div>
         }
         else
         {
             if (qa.ChildQuestions != null)
             {
                 <div class="row question child-question @(qa.Question.QuestionNumber==null?"parent-question":"")">
                 </div>
             }
             else
             {
                 <div class="row question @(qa.Question.QuestionNumber==null?"parent-question":"")">
                     @qa.Question.QuestionNumber  @qa.Question.Text
                 </div>
             }
             <div class="row answers">
                 @foreach (var answer in qa.Question.PossibleAnswers)
                 {
                     <div class="answer">
                         @{
    
                             <div class="answer">
                                 <label>
                                     @answer.AnswerText
                                     @Html.RadioButtonFor(m=>qa.SelectedAnswer, answer.Id)
                                 </label>
                             </div>
                             <div class="answer">
                                 <label>
    
                                 </label>
                             </div>
                         }
                     </div>
                 }
             </div>
         }
    
     }
     <input type="submit" value"Submit" />
 </form>

自然地,这会生成所有名称都相同的单选按钮,因此当我针对给定问题单击一个单选按钮时,先前的问题单选按钮将取消选中,新问题现在是唯一一个有选择的问题。

感谢任何帮助。

您需要在每个 ienumerable 的输入字段中指定索引。如果您使用 for loop 会好得多,但是使用您当前的代码可以这样做;

查看下面创建索引变量的代码,然后使用索引手动创建单选按钮。

@foreach (var qa in section.QAs)
{
   // create the QA index
   int indexQA = 0;

   if (qa.Question.QuestionNumber == 0)
   {
      ...
   }
   else
   {
      ...
      <div class="row answers">
         @foreach (var answer in qa.Question.PossibleAnswers)
         {
            // create possible answers index
            int indexPA = 0;
 
            <div class="answer">
            @{
               <div class="answer">

                  // create label for, with index
                  <label for="QA[@indexQA]PA[@indexPA]">
                     @answer.AnswerText
                  </label>

                  // create radio button, with index
                  <input type="radio" id="QA[@indexQA]PA[@indexPA]" name="Sections[0].QAs[@indexQA].Question.SelectedAnswer.Id" data-index="QA[@indexQA]" class="possible-answer" value="@answer.Id">

               </div>
               <div class="answer">
                  <label>
                  </label>
               </div>
             }
             </div>

             // increment possible answers index
             indexPA++;
          }
       </div>
    }
    
    // increment QA index
    indexQA++;
}

由于单选按钮具有不同的name属性,它们不会相互分组,所以我们需要制作一个取消选中其他按钮的脚本。

@section scripts{
   <script>
      $(document).ready(function(){
         $(".possible-answer").change(function(){
            var dataValue1 = $(this).data("index");
            
            // loop through all possible answers and check their data-index
            $(".possible-answer").each(function(){
               var dataValue2 = $(this).data("index");
               
               // if they have the same index, they belong to the same group, uncheck
               if(dataValue1 == dataValue2)
               {
                  $(this).prop("checked", false);
               }
            });
            
            // check the current clicked one
            $(this).prop("checked", true);
         });
      });
   </script>
}