[英]ASP.NET MVC 5 group of radio buttons
我正在開始我的第一個ASP.NET MVC項目,所以我有一個簡單的問題。 我有以下代碼:
foreach(var question in Model.GeneralQuestions)
{
<div class = "well">
<h3>
<strong>@question.QuestionString</strong>
</h3>
@foreach (var answer in question.PossibleAnswers)
{
@Html.RadioButtonFor(model => question.QuestionString, answer.Answer)
@Html.Label(answer.Answer)
<br />
}
</div>
}
Model.GeneralQuestions中的所有問題都是唯一的,因此單選按鈕應按名稱屬性分組(對於每個問題,一組單選按鈕)。 但是這段代碼只生成一個組,所以當我回答第二個問題時,首先會取消選擇。 我需要改變什么?
編輯
我的模型看起來像:
public class StudentViewModel
{
public Student Student { get; set; }
public List<Question> GeneralQuestions { get; set; }
public List<SubjectQuestions> SubjectQuestions { get; set; }
}
public class Student
{
public int StudentID { get; set; }
public string Index { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public virtual ICollection<Subject> Subjects { get; set; }
}
public class Question
{
public int QuestionID { get; set; }
public string QuestionString { get; set; }
public bool IsAssociatedWithSubject { get; set; }
public virtual ICollection<PossibleAnswer> PossibleAnswers { get; set; }
public virtual ICollection<Results> Results { get; set; }
}
public class SubjectQuestions
{
public Subject Subject { get; set; }
public List<Question> Questions { get; set; }
}
public class Results
{
public int ResultsID { get; set; }
public int QuestionID { get; set; }
public int? SubjectID { get; set; }
public int PossibleAnswerID { get; set; }
public virtual Question Question { get; set; }
public virtual PossibleAnswer PossibleAnswer { get; set; }
public virtual Subject Subject { get; set; }
}
在StudentViewModel的一個實例中,我保存了一個學生和他應該回答的所有問題(一般和他正在研究的科目相關)並將其傳遞給查看。 在視圖中,我將所有問題都以單一形式提出,它們都是無線電的類型。 那么,任何人都可以幫我分組單選按鈕並正確回發此表單嗎?
您的代碼存在許多問題,包括生成重復id
(無效的html),生成重復的name
屬性(這就是為什么您只創建一個組,但更重要的是,這將阻止您綁定到模型時回帖)並且你實際上並沒有綁定到有效的屬性。
您需要創建視圖模型來表示要顯示和編輯的內容,並在for
循環中生成單選按鈕(或使用EditorTemplate
),以便使用索引器正確命名它們。
查看模型
public class QuestionVM
{
public int ID { get; set; } // for binding
public string Text { get; set; }
[Required]
public int? SelectedAnswer { get; set; } // for binding
public IEnumerable<AnswerVM> PossibleAnswers { get; set; }
}
public class SubjectVM
{
public int? ID { get; set; }
[DisplayFormat(NullDisplayText = "General")]
public string Name { get; set; }
public List<QuestionVM> Questions { get; set; }
}
public class AnswerVM
{
public int ID { get; set; }
public string Text { get; set; }
}
public class StudentVM
{
public int ID { get; set; }
public string Name { get; set; }
// plus any other properties of student that you want to display in the view
public List<SubjectVM> Subjects { get; set; }
}
視圖
@model YourAssembly.StudentVM
@using(Html.BeginForm())
{
@Html.HiddenFor(m => m.ID)
@Html.DisplayFor(m => m.Name)
for(int i = 0; i < Model.Subjects.Count; i++)
{
@Html.HiddenFor(m => m.Subjects[i].ID)
@Html.DisplayFor(m => m.Subjects[i].Name) // will display "General" if no name
for (int j = 0; j < Model.Subjects[i].Questions.Count; j++)
{
@Html.HiddenFor(m => m.Subjects[i].Questions[j].ID)
@Html.DisplayFor(m => m.Subjects[i].Questions[j].Text)
foreach(var answer in Model.Subjects[i].Questions[j].PossibleAnswers )
{
<div>
@Html.RadioButtonFor(m => m.Subjects[i].Questions[j].SelectedAnswer, answer.ID, new { id = answer.ID})
<label for="@answer.ID">@answer.Text</label>
</div>
}
@Html.ValidationMessageFor(m => m.Subjects[i].Questions[j].SelectedAnswer)
}
}
<input type="submit" value="save" />
}
調節器
public ActionResult Edit(int ID)
{
StudentVM model = new StudentVM();
// populate your view model with values from the database
return View(model);
}
[HttpPost]
public ActionResult Edit(StudentVM model)
{
// save and redirect
}
注意我對模型隱含的數據庫結構感到有些困惑(例如,當SubjectQuestion
的null
值將SubjectID
標識為“常規”問題時,為什么需要Question
和SubjectQuestion
單獨模型)。 我建議你首先在GET方法中對一些值進行硬編碼,看看它是如何工作的,然后回發。
StudentVM model = new StudentVM();
model.ID = 1;
model.Name = "bambiinela";
model.Subjects = new List<SubjectVM>()
{
new SubjectVM()
{
Questions = new List<QuestionVM>()
{
new QuestionVM()
{
ID = 1,
Text = "Question 1",
SelectedAnswer = ?, // set this if you want to preselect an option
PossibleAnswers = new List<AnswerVM>()
{
new AnswerVM()
{
ID = 1,
Text = "Answer A"
},
new AnswerVM()
{
ID = 1,
Text = "Answer B"
}
}
},
new QuestionVM()
{
ID = 2,
Text = "Question 2",
PossibleAnswers = new List<AnswerVM>()
{
// similar to above
}
}
}
},
new SubjectVM()
{
ID = 1,
Name = "Math",
Questions = new List<QuestionVM>()
{
// similar to above
}
}
};
發布時,模型將填充每個主題中每個問題的所選答案的ID。 請注意DisplayFor()
用於某些屬性。 這些不會回發,因此如果返回視圖(例如ModelState
無效),則需要重新填充這些屬性。 或者,您可以生成只讀文本框或為這些屬性添加隱藏輸入。 我還建議你檢查生成的HTML,特別是看起來像的名稱屬性
<input type="radio" name="Subjects[0].Questions[0].SelectedAnswer" ...
讓您了解集合如何在回發后綁定到您的模型
訣竅是使用一個表達式(Html.RadioButtonFor的第一個參數),它包含一組每個單選按鈕更改的值。 在您的情況下,它將是問題列表中的索引。
以下是一些示例代碼:
@for (int i = 0; i < Model.GeneralQuestions.Count; i++)
{
var question = Model.GeneralQuestions[i];
@Html.Label(question.QuestionString)
<br />
foreach (var answer in question.PossibleAnswers)
{
@Html.RadioButtonFor(model =>
Model.GeneralQuestions[i].SelectedAnswerId, answer.Id)
@Html.Label(answer.Answer)
<br />
}
}
這會產生以下HTML:
<label for="Q1">Q1</label>
<br />
<input id="GeneralQuestions_0__SelectedAnswerId"
name="GeneralQuestions[0].SelectedAnswerId" type="radio" value="1" />
<label for="A01">A01</label>
<br />
<input id="GeneralQuestions_0__SelectedAnswerId"
name="GeneralQuestions[0].SelectedAnswerId" type="radio" value="2" />
<label for="A02">A02</label>
<br />
<label for="Q2">Q2</label>
<br />
<input id="GeneralQuestions_1__SelectedAnswerId"
name="GeneralQuestions[1].SelectedAnswerId" type="radio" value="11" />
<label for="A11">A11</label>
<br />
<input id="GeneralQuestions_1__SelectedAnswerId"
name="GeneralQuestions[1].SelectedAnswerId" type="radio" value="12" />
<label for="A12">A12</label>
<br />
為了完整起見,這里是使用的模型的簡化版本:
public class StudentViewModel
{
public List<Question> GeneralQuestions { get; set; }
}
public class Question
{
public int QuestionId { get; set; }
public string QuestionString { get; set; }
public ICollection<PossibleAnswer> PossibleAnswers { get; set; }
public int SelectedAnswerId { get; set; }
}
public class PossibleAnswer
{
public int Id { get; set; }
public string Answer { get; set; }
}
這是動作方法的代碼:
return View(new StudentViewModel
{
GeneralQuestions =
new List<Question>
{
new Question
{
QuestionString = "Q1",
PossibleAnswers =
new[]
{
new PossibleAnswer {Id = 1, Answer = "A01"},
new PossibleAnswer {Id = 2, Answer = "A02"}
}
},
new Question
{
QuestionString = "Q2",
PossibleAnswers =
new[]
{
new PossibleAnswer {Id = 11, Answer = "A11"},
new PossibleAnswer {Id = 12, Answer = "A12"}
}
},
}
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.