Group a collection in MVC View and update model in controller?
I have a View that displays a collection from a ViewModel, where the user can update a property for each collection item ("Level" of proficiency).
Here's the View:
@model Consultants.ViewModels.ProgramsViewModel
@{
ViewBag.Title = "Programkunskaper";
}
<h2>@ViewBag.Title</h2>
<div id="formDiv">
@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "myForm" }))
{
@Html.ValidationSummary(true)
<fieldset>
<legend>Ny arbetserfarenhet</legend>
<table>
<tr>
<th>
Program
</th>
<th>
Nivå
</th>
</tr>
@Html.EditorFor(m => m.ProgramSkills, "ProgramSkills")
@*Using editorformodel instead of for loop according to tip here: http://stackoverflow.com/questions/5420471/use-dropdownlistfor-with-foreach-in-asp-net-mvc-view*@
</table>
<p>
<input type="submit" value="Spara" />
</p>
</fieldset>
}
</div>
And the EditorFor template:
@model Consultants.Models.ProgramSkill
<tr>
<td>@Model.Program.Name
</td>
<td>
@Html.DropDownListFor(
model => model.Level,
new SelectList(new[] { 0, 1, 2, 3, 4, 5 },
Model.Level
)
)
</td>
</tr>
Here are my action methods (I know, using the Index view seems a little weird and I'll probably change that, but never mind that for now):
public ActionResult Index()
{
Consultant consultant = _repository.GetConsultantByUserName(User.Identity.Name);
ViewBag.Consultant = consultant;
if (consultant.ProgramSkills.Count == 0)
{
List<Program> programs = _repository.GetAllPrograms();
foreach (var program in programs)
{
consultant.ProgramSkills.Add(new ProgramSkill { Program = program });
}
_repository.Save();
}
ProgramsViewModel vm = new ProgramsViewModel();
vm.ProgramSkills = con开发者_开发知识库sultant.ProgramSkills.ToList();
return View(vm);
}
[HttpPost]
public ActionResult Index(ProgramsViewModel vm, FormCollection collection)
{
Consultant consultant = _repository.GetConsultantByUserName(User.Identity.Name);
List<ProgramSkill> programSkills = consultant.ProgramSkills.ToList();
for (int i = 0; i < programSkills.Count; i++)
{
var programSkill = programSkills[i];
programSkill.Level = vm.ProgramSkills[i].Level;
}
_repository.Save();
vm.ProgramSkills = programSkills;
return View(vm);
}
Now, even though this works fine, I realized that I need to be able to group the ProgramSkill items by it's Program.Category property. But then I'll get a couple of problems:
How do I group them and pass them in a ViewModel to the View?
The objects are Program, ProgramSkill and Consultant, where there's a Many to Many relationship between Program and Consultant, and ProgramSkill is the junction table (needed because it has the additional property "Level").
And if I were to have a Linq expression to group them according to this, and could make it into a ViewModel that the View can consume, how would I update the model again after posting back to the Controller?
It seems the code will get a lot more complicated, if it can be done at all, just for categorizing the ProgramSkill items by Program.Category. But at the same time, the View will have very poor usability if the items are not categorized...
Anyone know a good solution for this?
I think what you want to do is add another view model
ProgramSkillsModel
{
string Category {get;set;}
IList<ProgramSkill> Skills {get;set;}
}
Then in your controller Index()
ProgramsViewModel vm = new ProgramsViewModel();
vm.ProgramSkills = consultant.ProgramSkills.GroupBy(c => c.Category)
.Select(c => new ProgramSkillsModel{
Category = c.Key,
Skills = c.ToList(),
});
Hopefully that works. It's just pseudo code
精彩评论