2010-12-12 57 views
4

Aujourd'hui, j'ai eu le même problème toute la journée. Je suis toujours ASP MVC débutant, venant du monde Flex. Mais maintenant je travaille sur un projet ASP MVC.ASP MVC HTML formulaire POST Liste <Entity>

Je pense que c'est un problème assez complexe, donc j'essaie de décrire le problème très en détail. Donc, merci d'avance, que vous parlez le temps de passer par là!

Description du système:

Je suis en train de construire un "ProjectManagementSystem". Vous pouvez avoir plusieurs projets, où chaque projet a un nom et une description. Un projet a également une liste de détails supplémentaires. Un formulaire normal me permettrait d'entrer le nom et la description d'un nouveau projet, n'est-ce pas?

Maintenant, l'exigence est que des éléments de formulaire supplémentaires puissent être ajoutés. Par exemple, je veux ajouter une nouvelle entrée qui me permettra d'entrer le budget disponible pour tous les projets existants et nouveaux.

Le budget est un détail de projet supplémentaire. C'EST À DIRE. Lorsque l'élément a de pour le budget est ajouté, un nouveau détail de projet est ajouté à tous les projets.

Classes:

je suis arrivé la classe « Projet » qui a une liste de « ProjectDetails » et il fournit également une interface pour obtenir, ajouter et supprimer un « ProjectDetail » du « projet »:

public class Project : ProjectItem 
{ 
    public virtual IList<ProjectDetail> Details { get; set; } 

    public Project(string name, string description) : base(name, description) 
    { 
     Details = new List<ProjectDetail>(); 
    } 

    public Project() 
     : this("new project", "this is a new project") 
    { 

    } 

    public virtual void AddDetail(string name) 
    { 
     var detail = GetDetail(name); 

     if (detail == null) 
     { 
      detail = new ProjectDetail(name, "empty"); 
      detail.Project = this; 
      Details.Add(detail); 
     } 
    } 

    public virtual void RemoveDetail(string name) 
    { 
     var detail = GetDetail(name); 

     if (detail != null) 
     { 
      detail.Project = null; 
      Details.Remove(detail); 
     } 
    } 

    public virtual ProjectDetail GetDetail(string name) 
    { 
     ProjectDetail result = null; 

     foreach (ProjectDetail detail in Details) 
     { 
      if (detail.Name.Equals(name)) 
      { 
       result = detail; 
      } 
     } 

     return result; 
    } 
} 

La classe "ProjectDetail" ressemble à ceci:

public class ProjectDetail : ProjectItemDetail 
{ 
    [NotNull] 
    public virtual Project Project { get; set; } 

    public ProjectDetail(string name, string value) 
     : base(name, value) 
    { 

    } 

    public ProjectDetail() 
     : this("new project detail", "empty") 
    { 

    } 
} 

Notez que "ProjectDetail" hérite Nom et valeur f rom "ProjectItem" classe de base. J'essaye de créer la vue, qui me laissera éditer la propriété simple de la valeur de tous les «ProjectDetails» dans la liste de détails d'un «projet» particulier. Maintenant, chaque "ProjectDetail" est associé à un "FormElement" et ils sont appariés par leur propriété Name.

public class FormElement 
{ 
    public static string TYPE_UNKNOWN = "typeUnknown"; 
    public static string TYPE_NUMERIC = "typeNumeric"; 
    public static string TYPE_CHAR  = "typeChar"; 
    public static string TYPE_DATE  = "typeDate"; 

    [NotNull] 
    public virtual string Name { get; set; } 

    [NotNull] 
    public virtual int Position { get; set; } 

    [NotNull] 
    public virtual string Type { get; set; } 

    [NotNull] 
    public virtual Form Form { get; set; } 

    public FormElement(string name, int position, string type) 
    { 
     Name = name; 
     Position = position; 
     Type = type; 
    } 

    public FormElement() 
     : this("unknownFormElement", -1, TYPE_UNKNOWN) 
    { 

    } 

} 

Et le « Formulaire » classe:

public class Form : Entity 
{ 
    [NotNull] 
    public virtual string Name { get; set; } 

    public virtual IList<FormElement> FormElements { get; set; } 

    public Form(string name) 
    { 
     Name = name; 

     FormElements = new List<FormElement>(); 
    } 

    public Form() 
     : this("unknownWebform") 
    { 

    } 

    //public interface for getting, adding, deleting FormElement 
} 

Ainsi, la vue devra rendre le « formulaire » et remplir les éléments avec la valeur du liée « ProjectDetail ».

Ainsi, la vue est transmis dans un « ProjectEditModel »:

public class ProjectEditModel 
{ 
    public Form Form; 

    public Project Project; 

    public ProjectViewModel() {} 
} 

La vue suivante est fortement typée à « ProjectEditModel »:

<% using (Html.BeginForm("Edit", "Project", FormMethod.Post)) 
    {%> 

     <div> 
     <fieldset> 
      <legend>Edit Project</legend> 

      <div class="editor-label"> 
       <%: Html.LabelFor(m => m.Project.Name) %> 
      </div> 
      <div class="editor-field"> 
       <%: Html.TextBoxFor(m => m.Project.Name)%> 
      </div> 

      <div class="editor-label"> 
       <%: Html.LabelFor(m => m.Project.Description)%> 
      </div> 
      <div class="editor-field"> 
       <%: Html.TextBoxFor(m => m.Project.Description)%> 
      </div> 

      <% 

       foreach (var formElement in Model.Form.FormElements) 
       { 
        if (formElement.Type.Equals(Domain.Model.FormElement.TYPE_CHAR)) 
        { 
        %> 
         <div class="editor-label"> 
          <%: Html.Label(Model.Project.GetDetail(formElement.Name).Name)%> 
         </div> 
         <div class="editor-field"> 
          <%: Html.TextBoxFor(m => m.Project.GetDetail(formElement.Name).Value)%> 
         </div> 
        <% 
        } 
        if (formElement.Type.Equals(Domain.Model.FormElement.TYPE_NUMERIC)) 
        { 

        } 
       } 

      %> 

      <p> 
       <input type="hidden" name="Id" value="<%: Model.Project.Id %>" /> 
       <input type="submit" value="Save" /> 
      </p> 

     </fieldset> 
    </div> 

<% } %> 

Cela rend correctement et montrer un élément de forme pour chaque détail supplémentaire. Mais quand je referai le modèle, le constructeur aura été invoqué et ainsi je perdrai toutes mes références. PENG! J'ai lu, que MVC "fonctionne" comme ça et je suis prêt à accepter cela, mais comment puis-je résoudre mon problème alors? Vous avez besoin de plus d'informations?

Merci beaucoup, j'apprécierais vraiment l'aide!

+0

Pouvez-vous dire ce que vous attendez du serveur après la publication? Je ne comprends pas vraiment "le constructeur aura été invoqué et ainsi je perds toutes mes références". De quel constructeur parlez-vous? En outre, pouvez-vous montrer le code d'action de votre contrôleur? –

+0

Salut Andrey, ce que je veux dire, c'est que le constructeur du modèle de vue est appelé, donc toutes les informations (références) seront perdues. La méthode d'action POST dans le contrôleur recevra une nouvelle instance du modèle de vue. Ce n'est pas si important de savoir à quoi ça ressemble. Si je ne crée pas un nouveau "Projet" dans le constructeur du modèle de vue, les références au "Projet" seront même nulles. Je me suis assuré que les propriétés du modèle de vue étaient correctement remplies quand je l'ai passé à la vue en premier lieu. – dasnervtdoch

Répondre

2

MVC ne gérera pas automatiquement la façon dont vous essayez de créer dynamiquement le formulaire. Il ne liera pas votre collection d'éléments de formulaire à la collection car il n'a aucun moyen de les distinguer. Essayez la méthodologie décrite dans le document this blog post pour gérer le rendu de collection dynamique et la liaison de modèle.