2010-12-12 53 views
4

今天我一直在努力解決同一個問題。我仍然是來自Flex世界的ASP MVC初學者。但是現在我正在研究一些ASP MVC項目。ASP MVC HTML表單POST列表<Entity>

我認爲這是一個相當複雜的問題,因此我試圖描述非常詳細的問題。所以,提前謝謝你,你正在談論時間來通過這個!

系統介紹:

我試圖建立一個 「ProjectManagementSystem」。您可以有多個項目,其中每個項目都有一個名稱和一個說明。一個項目也有一個額外的細節清單。一個正常的表格會讓我輸入新項目的名稱和描述,對嗎?

現在,需求是,可以添加額外的表單元素。例如,我想添加一個新的輸入,它可以讓我輸入所有現有和新項目的可用預算。

預算是一個額外的項目細節。 IE瀏覽器。當預算的a from元素被添加時,新的項目細節將被添加到所有項目中。

類:

我得到了類「項目」具有「ProjectDetails」的列表,它也提供了一些接口獲取,添加並從「項目」刪除「ProjectDetail」:

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; 
    } 
} 

的 「ProjectDetail」 類看起來是這樣的:

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") 
    { 

    } 
} 

注意,認爲 「ProjectDetail」 繼承名稱和值f rom「ProjectItem」基類。

我想創建視圖,這將讓我編輯特定「項目」的詳細信息列表中的所有「ProjectDetails」的單個Value屬性。 現在,每個「ProjectDetail」都與一個「FormElement」相關聯,並且它們的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) 
    { 

    } 

} 

與「表」類:

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 
} 

因此,認爲將需要渲染的「表」,並填充相關的「ProjectDetail」的價值元素。

因此,鑑於被傳遞的「ProjectEditModel」:

public class ProjectEditModel 
{ 
    public Form Form; 

    public Project Project; 

    public ProjectViewModel() {} 
} 

以下幾種觀點是強類型爲「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> 

<% } %> 

這將正確渲染和顯示錶單元素爲每一個額外的細節。但是當我做POST回模型時,構造函數會被調用,這樣我就會釋放所有的引用。彭!

我已經閱讀過,MVC「正常工作」就像這樣,我願意接受,但我該如何解決我的問題呢?你需要更多的信息?

非常感謝,非常感謝幫助!

+0

你能告訴你回郵後你期望在服務器端得到什麼?我不是真的得到你的「構造函數會被調用,這樣我就會丟失所有的引用」。你在說什麼構造函數? 另外,你可以顯示你的控制器動作碼嗎? – 2010-12-13 21:42:31

+0

嗨安德烈,我的意思是調用視圖模型的構造函數,所以所有的信息(引用)都會丟失。控制器中的POST操作方法將傳遞視圖模型的新實例。知道它的樣子並不重要。如果我不在視圖模型構造函數中創建新的「項目」,則對「項目」的引用將甚至爲空。我確保視圖模型的屬性在我首先將其傳遞給視圖時正確填充。 – dasnervtdoch 2010-12-14 15:30:18

回答

2

MVC不會自動處理您嘗試動態創建表單的方式。它不會將您的表單元素集合綁定到集合上,因爲它們無法區分它們。

嘗試使用this blog post中描述的方法來處理動態集合呈現和模型綁定。