EditorTemplates Where 或 Groupby on Questionnaire

EditorTemplates Where or Groupby on Questionnaire

目前,我有一个调查问卷的工作原型,其中包含多个问题,每个问题都有多个答案选择。一切都很好地显示和保存。但是,我现在想在我的编辑视图中将 question/answers 分组到 'sections' 中。我尝试了几种不同的方法,但似乎都无法正常工作。没有节的工作代码如下:

编辑视图进度报告:

<div class="form-group">
    @Html.LabelFor(model => model.ReportAnswers, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.EditorFor(model => model.ReportAnswers)
    </div>
</div>

ReportAnswers.cshtml(编辑器模板)

<h3>
    Question
</h3>

<p>
    @Html.DisplayFor(x => x.Question.QuestionText)
</p>
@Html.HiddenFor(model => model.QuestionID)
@Html.HiddenFor(model => model.ReportID)

@foreach (var answer in Model.Question.PossibleAnswers)
{
    var id = string.Format("answer-{0}", answer.AnswerID);
    <p>
        @Html.HiddenFor(model => model.ReportAnswerID)

        @Html.RadioButtonFor(m => m.AnswerID, answer.AnswerID, new { id = id })
        <label for="@id">@answer.AnswerText</label>
    </p>
}

编辑控制器:

[HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit(ProgressReport progressReport)
    {
        if (ModelState.IsValid)
        {
            db.Entry(progressReport).State = EntityState.Modified;
            db.SaveChanges();

            foreach (ReportAnswer answer in progressReport.ReportAnswers)
            {
                        if (answer.QuestionID != null && answer.AnswerID != null)
                        {
                            db.Entry(answer).State = EntityState.Modified;
                            db.SaveChanges();
                        }                   

            }

            return RedirectToAction("Index");
        }
        ViewBag.ClientID = new SelectList(db.Clients, "ClientID", "ID", progressReport.ClientID);
        return View(progressReport);
    }

数据结构是 Sections -> Questions -> Answers 然后我有一个包含 QuestionID 和 AnswerID

的 ProgressReport table

我尝试在视图中进行 Groupby,但不确定如何正确调用 Editortemplate。其实我是可以用的,只是结果不如预期。该代码是:

@foreach (var group in Model.ReportAnswers.GroupBy(s => s.Question.SectionID))

谢谢!

数据结构片段:

您最好创建表示要在视图中显示的数据的视图模型

public class ReportVM
{
  public int ID { get; set; }
  // other properties or Report for display/editing
  public List<SectionVM> Sections { get; set; }
}
public class SectionVM
{
  public int ID { get; set; }
  public string Name { get; set; }
  // other properties or Report for display/editing
  public List<QuestionVM> Questions{ get; set; }
}
public class QuestionVM
{
  public int ID { get; set; }
  public string Title { get; set; }
  public int SelectedAnswer { get; set; }
  public List<Answer> PossibleAnswers { get; set; }
}

在控制器中,使用您的 .GroupBy() 查询来构建您的视图模型并添加每个部分及其相关 questions/answers

然后为 SectionVM 添加一个 EditorTempate

@model SectionVM
@Html.HiddenFor(m = > m.ID)
<h2>@Html.DisplayFor(m => m.Name)</h2>
@Html.EditorFor(m => m.Questions) // uses an EditorTemplate for QuestionVM (i.e. as per your current ReportAnswers template

并在主视图中

@Html.EditorFor(model => model.Sections)

我能够开发出一个解决方案...正确与否...不知道...但它确实有效。随意批评。我欢迎它。 :)

ProgressReportViewModel:

public class ProgressReportViewModel
{
    public int ReportID { get; set; }
    public DateTime ReportDateSubmitted {get; set;}
    public List<ReportAnswer>[] ReportAnswerSection { get; set; }
    public string[] SectionHeadings { get; set; }
    public string[] SectionDescriptions { get; set; }
}

编辑控制器:

public ActionResult Edit(int? id)
    {
        var viewModel = new ProgressReportViewModel();

       //  Get the section in order of defined display order
        var questionsection = (from s in db.QuestionSections
                                orderby s.SectionDisplayOrder
                                select new{
                                    s.SectionName,
                                    s.SectionDesc
                                });

        viewModel.SectionHeadings = new string[11];
        viewModel.SectionDescriptions = new string[11];
        viewModel.ReportAnswerSection = new List<ReportAnswer>[11];

        int i = 0;
        foreach(var section in questionsection)
        {
            //  Loop through sections and get the name, desc and the questions/answers
            viewModel.SectionHeadings[i] = section.SectionName.ToString();
            viewModel.SectionDescriptions[i] =   section.SectionDesc;
            viewModel.ReportAnswerSection[i] = db.ReportAnswers.Where(q => q.Question.SectionID == i+1 && q.ReportID == id).Include(s => s.Question.QuestionSection).OrderBy(q => q.Question.DisplayOrder).ToList();
            i=i+1;
        }

        var report = (from r in db.ProgressReports
                      where r.ReportID == id
                      select new
                      {
                          r.ReportID,
                          r.ReportDateSubmitted,
                          r.ClientID
                      }).SingleOrDefault();
        viewModel.ReportID = report.ReportID;
        viewModel.ReportDateSubmitted = report.ReportDateSubmitted ?? DateTime.MinValue;


        return View(viewModel);
    }



    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit(ProgressReportViewModel progressReport)
    {
        if (ModelState.IsValid)
        {
            ProgressReport PR = db.ProgressReports.Where(x => x.ReportID == progressReport.ReportID).SingleOrDefault();


            //db.ProgressReports.Attach(progressReport);

            db.Entry(PR).State = EntityState.Modified;
            db.SaveChanges();

            for (var i = 0; i <= 10; i++ )
            {
                foreach (ReportAnswer answer in progressReport.ReportAnswerSection[i]) //.ReportAnswers)
                {
                    SaveAnswers(answer);
                }
            }

            return RedirectToAction("Index", "Home");
        }
        return View(progressReport);
    }

ReportAnswers 编辑器模板

<h3>
Question
</h3>

<p>
@Html.DisplayFor(x => x.Question.QuestionText)
</p>
@Html.HiddenFor(model => model.QuestionID)
@Html.HiddenFor(model => model.ReportID)

@foreach (var answer in Model.Question.PossibleAnswers)
{
var id = string.Format("answer-{0}", answer.AnswerID);
<p>
    @Html.HiddenFor(model => model.ReportAnswerID)

    @Html.RadioButtonFor(m => m.AnswerID, answer.AnswerID, new { id = id })
    <label for="@id">@answer.AnswerText</label>
</p>
}

编辑视图:

@for(var i = 0; i<=10; i++)
    {
        <h4>@Html.DisplayFor(model => model.SectionHeadings[i]) </h4>
        <p>@Html.DisplayFor(model => model.SectionDescriptions[i]) </p>
        @Html.EditorFor(model => model.ReportAnswerSection[i])
    }

我选择做这些数组是因为至少有一个部分我需要拦截来做一些特别的事情。否则所有其他部分都是典型的。 这似乎可行,但如前所述,我欢迎任何人提出任何批评。

祝你有愉快的一天!