ネストされたリピータの動作にループを使用する限り、for
これが MVC でこれを行う最良の方法だと思います。ただし、専用の ViewModel を使用することをお勧めします。
ビューモデル:
public class RadioQuestionListViewModel
{
public IEnumerable<RadioQuestionViewModel> Questions {get;set;}
}
public class RadioQuestionViewModel
{
public int QuestionNumber {get;set;}
public string InputName {get;set;}
public string QuestionPart1 {get;set;}
public string QuestionPart2 {get;set;}
public IEnumerable<RadioAnswerViewModel> PossibleAnswers {get;set;}
}
public class RadioAnswerViewModel
{
public int AnswerId {get;set;}
public string Text {get;set;}
}
コントローラ:
public ActionResult Details(int id)
{
var model = GetRadioQuestionListModelById(id);
return View(model);
}
意見:
<% foreach (var question in Model) { %>
<h3>Question <%: question.QuestionNumber %></h3>
<p><%: question.QuestionPart1 %></p>
<p><%: question.QuestionPart2 %></p>
<% foreach (var answer in question.PossibleAnswers) { %>
<%: Html.RadioButton(question.InputName, answer.AnswerId) %>
<%: answer.Text %>
<% } %>
<% } %>
このアプローチにはいくつかの利点があります。
- ビュー コードがデータ アクセス クラスに依存するのを防ぎます。ビュー コードは、目的のビュー モデルを HTML にレンダリングする方法を決定することのみを担当する必要があります。
- これにより、非表示関連のロジックがビュー コードから除外されます。後で質問をページングすることを決定し、1-whatever の代わりに質問 11-20 を表示している場合、まったく同じビューを使用できます。これは、コントローラーが表示する質問番号を計算することを処理するためです。
Array.IndexOf(Model.ToArray(), question)
これにより、ループ内で と データベースのラウンドトリップを実行することを簡単に回避for
できます。これは、ページにいくつかの質問がある場合にかなりコストがかかる可能性があります。
もちろん、ラジオ ボタンには入力名と値を関連付ける必要があります。そうしないと、フォームが送信されたときにこの情報を取得する方法がありません。コントローラに入力名の生成方法を決定させることで、メソッドがメソッドにどのようにDetails
対応するかがより明確になりますSaveAnswers
。
可能な実装は次のGetRadioQuestionListModelById
とおりです。
public RadioQuestionListViewModel GetRadioQuestionListModelById(int id)
{
// Make sure my context gets disposed as soon as I'm done with it.
using(var context = new Models.Entities())
{
// Pull all the questions and answers out in a single round-trip
var questions = context.Questions
.Where(r => r.PROMId == id)
.Select(r => new RadioQuestionViewModel
{
QuestionPart1 = r.q.QuestionPart1,
QuestionPart2 = r.q.QuestionPart2,
PossibleAnswers = r.a.Select(
a => new RadioAnswerViewModel
{
AnswerId = a.AnswerId,
Text = a.Text
})
})
.ToList();
}
// Populate question number and name
for(int i = 0; i < questions.Count; i++)
{
var q = questions[i];
q.QuestionNumber = i;
q.InputName = "Question_" + i;
}
return new RadioQuestionListViewModel{Questions = questions};
}