2016-11-08 40 views
1

我有一個應用程序來創建和編輯調查。每項調查都包含一組問題和相關答案(答案)。在創建調查時,問題集合將從單獨的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?並且可以具有05之間的值(或null如果用戶還沒有給出的響應)。理想情況下,我希望將其渲染爲單選按鈕以選擇可能的值。

+0

首先,你不能使用'foreach'循環來生成表單控件集合(參見[這個答案](http://stackoverflow.com/questions/30094047/html-table-to -ado淨數據表/ 30094943#30094943))。第二,(我假設)一個問題只會有一個答案,所以你查看模型的「問題」應該有一個「答案」,而不是「答案」集合 –

+0

@StephenMuecke調查有一組問題,但作爲可以有很多調查實例,每個調查中的問題都可以有答案。例如,調查1中的問題1可能具有3的答案,而在不同的調查中,同一問題可能具有7的答案 – totalitarian

+0

在那種情況下,爲什麼不使用另一個foreach循環? –

回答

1

首先,你需要創建代表一個問題,它的答案

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)似乎不必要的,因爲你已經擁有的AnswerSurvey關聯的集合(每個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); 
+0

再次感謝。我已經將其納入我的應用程序,一切運行順利:) – totalitarian

+1

這真的取決於你。將代碼用於將數據模型映射到單獨服務中的視圖模型(或使用[automapper](http://automapper.org/)之類的工具),可以使您的控制器代碼更加清晰,並且符合我的偏好。我通常使用像'MyViewModel model = Map(dataModel); 'ConfigureViewModel(model);'其中'Map()'返回基於數據模型的視圖模型,'ConfigureViewModel()'創建'SelectList' –

相關問題