我正在建立一份调查问卷。问卷有多个部分,每个部分有多个问题,每个问题可以有一个到多个答案。每个问题可以是不同的类型(单选按钮,复选框,文本......)。
我将我的表放在模型中并循环遍历sections表以显示部分,循环显示问题以显示问题,循环answerOptions以填充答案:
<fieldset>
<legend>Fields</legend>
<%foreach (var s in Model.Sections)
{ %>
<h3><%=s.SCTN_TXT %></h3>
<% var QuestsInSect = Model.GetQuestionsBySectionID(s.SCTN_ID);%>
<%foreach (var q in QuestsInSect){%>
<h4><%=q.QSTN_TXT %><%=q.QSTN_ID.ToString() %></h4>
<% var answers = Model.GetAnswerOptionByQuestionID(q.QSTN_ID); %>
<%if (q.QSTN_TYP_ID>= 3)
{%>
<%:Html.TextBox(q.QSTN_ID.ToString())%>
<%}
else if (q.QSTN_TYP_ID == 1)
{ %>
<%var answerOptions = Model.GetDropDownListAnswerOptionByQuestionID(q.QSTN_ID);%>
<%:Html.DropDownList(q.QSTN_ID.ToString(), answerOptions)%>
<%}
else
{ %>
<% foreach (var ao in answers)
{ %>
<br />
<%:Html.CheckBox(q.QSTN_ID.ToString())%>
<%=ao.ANS_VAL%>
<% }
}
}
} %>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
在我的控制器中,我遍历collection.Allkeys以找出每个问题的答案:
[HttpPost]
public ActionResult Create(FormCollection collection)
{
try
{
// TODO: Add insert logic here
List<ASSMNT_RESP> arList = new List<ASSMNT_RESP>();
foreach (string key in collection.AllKeys)
{
QSTN q = _model.GetQuestionByQuestionID(int.Parse(key));
IEnumerable<ANS_OPTN> aos = _model.GetAnswerOptionByQuestionID(int.Parse(key));
ASSMNT_RESP ar = new ASSMNT_RESP();
ar.QSTN_ID = int.Parse(key);
ar.ASSMNT_ID = 1;
if (q.QSTN_TYP_ID == 1)//dropdown
{
//do something
}
else if (q.QSTN_TYP_ID == 2)//checkboxlist
{
//do something
}
else
{
//do something
}
//_model.AddAssessmentResponse(ar);
System.Diagnostics.Trace.WriteLine(key + "---"+ collection[key]);
}
//_model.Save();
return RedirectToAction("Index");
}
catch
{
return View();
}
}
它有效,但我认为这不是一个非常好的设计。看来我在视图中有太多的逻辑。我想将视图和控制器中的逻辑移动到模型中。你能推荐一种更简单/更清洁的方法吗?
感谢。
答案 0 :(得分:0)
我不是MVC的专家,但我认为使用基于您构建的自定义模型类的强类型视图可以获得很多好处。由这种模型公开的属性可以嵌套(即,顶级模型可以由属性组成,每个属性也是自定义类)。从概念上讲,类似于:
public class MyTopLevelModel
{
public MySubModel1 SubModel1 { get; set; }
public MySubModel2 SubModel2 { get; set; }
}
public class MySubModel1
{
public string AProperty { get; set; }
public int AnotherProperty { get; set; }
}
您也可以在类定义中包含集合。然后,您可以使用指定是否需要特定属性的属性,一系列允许值等来装饰各个属性。
但这是一个很大的主题,而这只会触及表面。 FWIW,我从Steven Sanderson的Pro ASP.NET MVC2框架书中得到了很多。
答案 1 :(得分:0)
让您的viewmodel更明确。
public class ViewModel
{
public IList<SectionViewModel> Sections {get;set;}
}
public class SectionViewModel
{
public IList<QuestionViewModel> Questions {get;set;}
}
public class QuestionViewModel
{
public IList<AnswerViewModel> Answers {get;set;}
}
在你看来,你可以做这样的事情(我正在使用剃须刀):
@foreach(var section in Model.Sections)
{
<h3>@section.Name</h3>
foreach(var question in section.Questions)
{
<h4>@question.Name</h4>
foreach(var question in section.Questions)
{
@Html.EditorFor(x=> question.Answers)
}
}
}
然后为您的Answer ViewModel创建一个编辑器模板。