2010-12-12 4 views
4

今日私は一日中同じ問題に苦しんでいます。私はまだFlex MVC初心者ですが、Flexの世界から来ています。しかし、今私はいくつかのASP MVCプロジェクトに取り組んでいます。ASP MVC HTMLフォームPOSTリスト<Entity>

私はこれはかなり複雑な問題だと思うので、非常に詳細な問題を説明しようとしています。あなたがこれを通過する時間を話していることを、事前に感謝します!

システムの説明:

私は "ProjectManagementSystem" を構築しようとしています。複数のプロジェクトを持つことができます。各プロジェクトには名前と説明があります。プロジェクトにはさらに詳細なリストがあります。通常のフォームでは、新しいプロジェクトの名前と説明を入力できますか?

ここで追加のフォーム要素を追加できるという要件があります。たとえば、新しい入力を追加して、すべてのの既存の予算と新しいプロジェクトの予算を入力します。

予算は追加プロジェクトの詳細です。 IE。予算のfrom要素が追加されると、新しいプロジェクトの詳細がすべてのプロジェクトに追加されます。

クラス:

は、私が「ProjectDetails」のリストを持つクラス「プロジェクト」を持って、それはまた、取得、追加および「プロジェクト」から「ProjectDetail」を削除するために、いくつかのインタフェースを提供します。

"ProjectDetail" は名前と値Fを継承することを、

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

    } 
} 

注:

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" クラスは、このようになります。 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

ポストバック後にサーバー側で何が得られると思いますか?私は実際にあなたの "コンストラクタが呼び出され、この方法で私はすべての私の参照を緩める"を取得していない。あなたが話しているコンストラクタは何ですか? また、コントローラのアクションコードを表示できますか? –

+0

こんにちはアンドレイ、私は、ビューモデルのコンストラクタが呼び出されるので、すべての情報(参照)が失われるということです。コントローラ内のPOSTアクションメソッドには、ビューモデルの新しいインスタンスが渡されます。どのように見えるかは重要ではありません。ビューモデルのコンストラクタで新しい "プロジェクト"を作成しない場合、 "プロジェクト"への参照もnullになります。私は最初にビューに渡したときに、ビューモデルのプロパティが正しく設定されていることを確認しました。 – dasnervtdoch

答えて

2

MVCは、フォームを動的に作成する方法を自動的には処理しません。フォーム要素のコレクションをコレクションと区別する方法がないため、フォーム要素のコレクションをコレクションにバインドしません。

this blog postに記載されている方法を試して、動的コレクションのレンダリングとモデルのバインドを処理してください。

関連する問題