如何将动态问题集合与动态答案集合绑定到视图模型?
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>
}
我有一个应用是多项选择调查。问题是从数据库中加载的,答案选项也是从数据库中加载的。我想将响应绑定到模型,但我不确定如何实现。这是我的 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>
}