2016-11-08 1 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); 
} 

이된다 내보기 모델에 모든 질문이 채워지지만 각 질문에는 답변 모음이 포함되어 있습니다. 보기에서이 설문과 관련된 각 질문에 대한 대답 만 표시하고 편집하려면 어떻게합니까? 응답 int?하며 (사용자가 아직 응답을 제공하지 않은 경우 나 null) 05 사이의 값을 가질 수

@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="????" /> 
} 

참고. 이상적으로 이것은 가능한 값을 선택하는 라디오 버튼으로 렌더링되기를 바랍니다.

+0

먼저 ([이 답변] 참조 (http://stackoverflow.com/questions/30094047/html-table-to 컬렉션에 대한 양식 컨트롤을 생성하는'foreach' 루프를 사용할 수 없습니다 수 있습니다 -ado-net-datatable/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" /> 
} 

하는 이미 Survey과 관련된 Answer의 컬렉션이 있습니다 (각 AnswerQuestion 속성이 포함로 GET 방식의 값을 얻기 위해

public ActionResult Edit(SurveyResponseVM model) 

에 다시 게시 할 예정입니다, 당신의 두번째 쿼리 (db.Questions.Where(q => q.isActive) 불필요한 보인다. 코드는

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' –

관련 문제