2011-03-25 2 views
3

J'ai une vue qui affiche une collection à partir d'un ViewModel, où l'utilisateur peut mettre à jour une propriété pour chaque élément de collection ("niveau" de compétence).Regrouper une collection dans MVC Afficher et mettre à jour le modèle dans le contrôleur?

est ici la vue:

@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> 

Et le modèle EditorFor:

@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> 

Voici mes méthodes d'action (je sais, en utilisant l'affichage d'index semble un peu bizarre et je vais probablement changer ça, mais ça ne fait rien pour l'instant):

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 = consultant.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); 
    } 

Maintenant, même si cela fonctionne bien, j'ai réalisé que je devais être capable de grouper les éléments ProgramSkill par sa propriété Program.Category. Mais alors je vais avoir quelques problèmes:

Comment puis-je les regrouper et les transmettre dans un ViewModel à la vue? Les objets sont Program, ProgramSkill et Consultant, où il existe une relation Many to Many entre le programme et le consultant, et ProgramSkill est la table de jonction (nécessaire car elle possède la propriété supplémentaire "Level").

Et si je devais avoir une expression Linq pour les regrouper en fonction de ceci, et que je pourrais en faire un ViewModel que la vue peut consommer, comment pourrais-je mettre à jour le modèle après l'avoir renvoyé au contrôleur?

Il semble que le code deviendra beaucoup plus compliqué, si cela peut être fait, juste pour catégoriser les éléments ProgramSkill par Program.Category. Mais dans le même temps, la vue aura une très mauvaise utilisabilité si les articles ne sont pas catégorisés ...

Quelqu'un sait une bonne solution pour cela?

Répondre

0

Je pense que ce que vous voulez faire est d'ajouter un autre modèle de vue

ProgramSkillsModel 
{ 
    string Category {get;set;} 
    IList<ProgramSkill> Skills {get;set;} 
} 

Ensuite, dans votre contrôleur Index()

ProgramsViewModel vm = new ProgramsViewModel();   
vm.ProgramSkills = consultant.ProgramSkills.GroupBy(c => c.Category) 
        .Select(c => new ProgramSkillsModel{ 
Category = c.Key, 
Skills = c.ToList(), 
}); 

Espérons que fonctionne. C'est juste pseudo code

Questions connexes