2012-01-19 14 views
2

在我目前的項目我有一個是視圖模型的幾個實例包含子的集合查看模型,像這樣:在子視圖模型爲什麼在EditorTemplate中渲染集合時會出現錯誤的表單元素名稱?

public class ParentViewModel 
{ 
    public ParentViewModel() 
    { 
     Children = new List<ChildViewModel>(); 
    } 

    public List<ChildViewModel> Children { get; set; } 
} 

public class ChildViewModel 
{ 
    public string Name { get; set; } 
    public int Age { get; set; } 
} 

的數據是這樣的,它可以在兩個使用一個創建和更新表單。考慮到這一點,我一直試圖使用EditorFor爲這些子視圖模型集合生成表單元素。

我知道,如果創建一個EditorTemplate,只是喂收集到EditorFor像這樣:

@Html.EditorFor(vm => vm.Children) 

是EditorFor會自動遍歷集合和EditorTemplate適用於每個單獨的項目。我遇到的問題是,如果我希望對每三個項目採取特定操作,將兩個項目渲染到同一個表格行中,或者需要強制EditorFor使用特定的EditorTemplate,這很好除了出現一個奇怪的問題。

這是我的測試EditorTemplate

@model List<Sandbox.Models.ChildViewModel> 

<table> 
@for(int i = 0, j = 1; i < Model.Count - 1; i+=2) 
{ 
    <tr> 
     <td> 
      @Html.TextBoxFor(o => o[i].Age) 
     </td> 
     @if(j < Model.Count) 
     { 
      <td> 
       @Html.TextBoxFor(o => o[j].Age) 
      </td> 
     } 
    </tr> 
} 
</table> 

和包含EditorFor呼叫

@model Sandbox.Models.ParentViewModel 

<html> 
    <head> 
     <title>title</title> 
    </head> 
    <body> 
     <div> 
      @using(Html.BeginForm()) { 
       @Html.EditorFor(o => o.Children, "ChildrenTemplate") 
       <input type="submit" /> 
      } 
     </div> 
    </body> 
</html> 

當使用上述EditorTemplate產生的形式的圖,由EditorTemplate產生的形式的元件畸形名稱屬性。他們在那裏應該是

Children[1].Age 

他們是不是

Children.[1].Age 

這完全拋出模型綁定不正常的,它會拒絕重新填充表單提交父視圖模型。

我已經能夠解決這個問題的唯一方法是使EditorTemplate的模型成爲父視圖模型而不是子視圖模型的列表,這強烈地限制了我可以使用模板的能力我擁有相同的子視圖模型集合的幾個位置,我沒有包含它的父模型。

在這一點上,我知道以下選項:

  1. 更改EditorTemplate父視圖模型,它通過重複使用模板的能力限制的模型。
  2. 創建自定義模型聯編程序或操作篩選器,以便在模型聯編程序可以看到問題之前嘗試清理表單名稱。
  3. 找出如何使當前的設置工作。

任何和所有的幫助表示讚賞。

回答

1

你可以點點改變你的代碼,就像

包含EditorFor調用視圖

<table> 
    @for (int i = 0; i < Model.Children.Count; i++) 
    { 
     @Html.EditorFor(o => o.Children[i]) //also you could mention the template name 
    } 
</table> 

這裏是我的測試EditorTemplate

@model Sandbox.Models.ChildViewModel 

    <tr> 
     <td> 
      @Html.TextBoxFor(o => o.Name) 
     </td>    
     <td> 
      @Html.TextBoxFor(o => o.Age) 
     </td>    
    </tr> 

詳情 http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx HTTP: //blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/

0

在你ChildrenTemplate.cshtml

@model List<Sandbox.Models.ChildViewModel> 
<table> 
    @Html.EditorForModel() 
</table> 

,然後定義它會自動被渲染爲集合中的每個元素的編輯模板(~/Views/Shared/EditorTemplates/ChildViewModel.cshtml):

@model Sandbox.Models.ChildViewModel 
<tr> 
    <td> 
     @Html.TextBoxFor(x => x.Name) 
    </td>    
    <td> 
     @Html.TextBoxFor(x => x.Age) 
    </td>    
</tr> 

這樣你就不需要在代碼中編寫任何循環,並且不必擔心輸入字段的錯誤名稱。它按照慣例工作。