根据相关数据构建编辑视图模型
我有一个应用程序来创建和编辑调查。每项调查都包含一组问题和相关答案(答案)。在创建调查时,问题集合将从单独的Questions
表中生成。每年都会为每个使用同一组问题的用户创建一项新的调查问卷,以便随时间进行比较。根据相关数据构建编辑视图模型
创建调查时,每个问题的答案都会保存下来,但是用户可能没有对每个问题给出答复,现在我必须构建一个视图来编辑现有答案。
模型
public class Survey
{
public int ID { get; set; }
public int AreaID { get; set; }
public Status Status { get; set; }
public DateTime AssessmentDate { get; set; }
public virtual Area Area { get; set; }
public virtual ICollection<Answer> Answers { get; set; }
}
public class Question
{
public int ID { get; set; }
public string QuestionText { get; set; }
public virtual ICollection<Answer> Answers { get; set; }
}
public class Answer
{
public int ID { get; set; }
public int? Response { get; set; }
public int QuestionID { get; set; }
public int SurveyID { get; set; }
public virtual Question Question { get; set; }
public virtual Survey Survey{ get; set; }
}
这里是我的视图模型,我用它来创建我的观点为编辑屏幕
public class SurveyResponseViewModel
{
public Assessment Assessment { get; set; }
public IEnumerable<Question> Questions { get; set; }
}
,并在GET方法的代码
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Survey survey = db.Surveys.Find(id);
var viewModel = new SurveyResponseViewModel
{
Survey = survey,
Areas = new SelectList(db.Areas, "ID", "SubLevel").ToList(),
Questions = db.Questions.Where(q => q.isActive)
};
if (survey == null)
{
return HttpNotFound();
}
return View(viewModel);
}
这用所有问题填充我的视图模型,但每个问题都包含一组答案。如何在视图中仅显示和编辑与此调查相关的每个问题的答案?
@foreach (var question in Model.Questions)
{
// Display the question
@Html.Raw(question.QuestionText)
// How to create an input for the associated response??
<input type="text" name="????" placeholder="Enter a number..." value="????" />
}
注意,该响应是int?
并且可以具有0
和5
之间的值(或null
如果用户还没有给出的响应)。理想情况下,我希望将其渲染为单选按钮以选择可能的值。
首先,你需要创建代表一个问题,它的答案
public class QuestionVM
{
public int QuestionID { get; set; }
public string QuestionText { get; set; }
public int? AnswerID { get; set; }
[Range(0, 5)]
public int? Response { get; set; }
}
,主视图模型会(请注意,视图模型不应该包含在编辑时的一些数据模型属性)视图模型
public class SurveyResponseVM
{
public int ID { get; set; } // this will be bound by the route value
[Required(ErrorMessage = "Please select an area")]
[Display(Name = "Area")]
public int? SelectedArea { get; set; }
public IEnumerable<SelectListItem> AreaList { get; set; }
.... // other properties of assessment that you need for the view
public List<QuestionVM> Questions { get; set; }
}
所以,在视图中可以使用
@model SurveyResponseVM
....
@using (Html.BeginForm())
{
@Html.DropDownListFor(m => m.SelectedArea, Model.AreaList)
....
for(int i = 0; i < Model.Questions.Count; i++)
{
<h3>@Model.Questions[i].QuestionText</h3>
@Html.HiddenFor(m => m.Questions[i].AnswerID)
for (int j = 0; j < 6; j++)
{
<label>
@Html.RadioButtonFor(m => m.Questions[i].Resonse, j, new { id = "" })
<span>@j</span>
</label>
}
}
<input type="submit" value="Save" />
}
这会后回
public ActionResult Edit(SurveyResponseVM model)
对于GET方法得到的值,你的第二查询(db.Questions.Where(q => q.isActive)
似乎不必要的,因为你已经拥有的Answer
与Survey
关联的集合(每个Answer
包含Question
财产。你的代码可以
Survey survey = db.Surveys.Find(id);
if (survey == null) // check for null here
{
return HttpNotFound();
}
IEnumerable<Area> areas = db.Areas;
SurveyResponseVM model = new SurveyResponseVM()
{
ID = survey.ID,
SelectedArea = survey.AreaID,
.... // other properties of Survey as required for the view
AreaList = new SelectList(areas , "ID", "SubLevel"),
Questions = survey.Answers.Select(x => new QuestionVM()
{
QuestionText = x.Question.QuestionText,
AnswerID = x.ID,
Response = x.Response
})
};
return View(model);
再次感谢。我已经将其纳入我的应用程序,一切运行顺利:) – totalitarian
这真的取决于你。将代码用于将数据模型映射到单独服务中的视图模型(或使用[automapper](http://automapper.org/)之类的工具),可以使您的控制器代码更加清晰,并且符合我的偏好。我通常使用像'MyViewModel model = Map(dataModel); 'ConfigureViewModel(model);'其中'Map()'返回基于数据模型的视图模型,'ConfigureViewModel()'创建'SelectList' –
首先,你不能使用'foreach'循环来生成表单控件集合(参见[这个答案](http://stackoverflow.com/questions/30094047/html-table-to -ado净数据表/ 30094943#30094943))。第二,(我假设)一个问题只会有一个答案,所以你查看模型的“问题”应该有一个“答案”,而不是“答案”集合 –
@StephenMuecke调查有一组问题,但作为可以有很多调查实例,每个调查中的问题都可以有答案。例如,调查1中的问题1可能具有3的答案,而在不同的调查中,同一问题可能具有7的答案 – totalitarian
在那种情况下,为什么不使用另一个foreach循环? –