2012-01-20 7 views
2

私は、行のリストを表示する部分的なビューを作成しました。行の一部のフィールドは、テキストボックス、チェックボックスなどを使用して編集可能です。部分ビューで一括保存を実行するにはどうすればよいですか?

親ビューには、更新された行のコレクション全体を投稿する「送信」ボタンがあり、更新された行ごとに一度投稿するのではなく、グループの更新を行うことができます。ここで

は、私が持っているものです。

public class GroupModel { 
    public string SomeGenericProperty { get; set; } 
    public IEnumerable<ItemModel> Items { get; set; } 
} 

public class ItemModel { 
    public long ID { get; set; } 
    public string Field1 { get; set; } 
    public string Field2 { get; set; } 
} 

それから私は、ビュー "GroupDetails" があります。

@model MyNamespace.GroupModel 
... 
@using (Html.BeginForm("SaveItems", "Home")) { 
    <fieldset> 
    ... 
    @Html.Partial("ItemList", Model.Items) 
    ... 
    <input type="submit" value="Approve" /> 
    </fieldset> 
} 

と部分ビューを "ITEMLIST":

@model IEnumerable<MyNamespace.ItemModel> 
<table> 
    <tr> 
    <th> 
     &nbsp; Field 1 &nbsp; 
    </th> 
    <th> 
     &nbsp; Field 2 &nbsp; 
    </th> 
    <th> 
    </th> 
    </tr> 
    @foreach (var item in Model) { 
    <tr> 
     <td> 
     &nbsp; 
     @Html.TextBoxFor(modelItem => item.Field1) 
     &nbsp; 
     </td> 
     <td> 
     &nbsp; 
     @Html.TextBoxFor(modelItem => item.Field2) 
     &nbsp; 
     </td> 
     <td> 
     @Html.HiddenFor(i => item.ID) 
     </td> 
    </tr> 
    } 
</table> 

しかし、私ポストでは、部分ビューからの情報はポストされていません。 GroupModelオブジェクトのItemsプロパティはnullです。

これは正しい方法はありますか?

答えて

4

私は常にエディタテンプレートを使用することをお勧めします。あなたのコードがうまくいかない理由は、部分的な部分を使用し、この部分的に親のテンプレートコンテキストを継承しないためです。つまり、内部で使用されるヘルパーが入力フィールドに間違った名前を生成します。例えば

あなたのページのソースコードを見れば、あなたは、この表示されます。

<td> 
    &nbsp; 
    <input type="text" name="[0].Field1" id="[0]_Field1" /> 
    &nbsp; 
</td> 

の代わりに、ある正しい名前:

<td> 
    &nbsp; 
    <input type="text" name="Items[0].Field1" id="Items[0]_Field1" /> 
    &nbsp; 
</td> 

私はfollowing blog postを読んで、あなたをお勧めしますデフォルトのモデルバインダーが予期しているワイヤー形式をよりよく理解するためです。

だから、最初にあなたのメインビューを固定することにより開始し、エディタのテンプレートで部分的に置き換える:

@model MyNamespace.GroupModel 
@using (Html.BeginForm("SaveItems", "Home")) 
{ 
    <fieldset> 
     ... 

     <table> 
      <thead> 
       <tr> 
        <th>&nbsp; Field 1 &nbsp;</th> 
        <th>&nbsp; Field 2 &nbsp;</th> 
        <th></th> 
       </tr> 
      </thead> 
      <tbody> 
       @Html.EditorFor(x => x.Items) 
      </tbody> 
     </table> 

     ... 
     <input type="submit" value="Approve" /> 
    </fieldset> 
} 

、その後、モデルの各要素に対してレンダリングされるカスタムエディタのテンプレート(~/Views/Shared/EditorTemplates/ItemModel.cshtml定義 - この作品をこれはコントローラ内で再利用したい場合は~/Views/Shared/EditorTemplatesの内部か、Homeコントローラのみでこのテンプレートを使用できるようにする場合は~/Views/Home/EditorTemplatesの内部にある必要があります。テンプレートの名前はコレクションのタイプでなければなりませんあなたのケースはItemModel.cshtmlです):

@model MyNamespace.ItemModel 
<tr> 
    <td> 
     &nbsp; 
     @Html.TextBoxFor(x => x.Field1) 
     &nbsp; 
    </td> 
    <td> 
     &nbsp; 
     @Html.TextBoxFor(x => x.Field2) 
     &nbsp; 
    </td> 
    <td> 
     @Html.HiddenFor(x => x.ID) 
    </td> 
</tr> 

今、すべてはあなたのコントローラのアクションで結構なバインドします:

[HttpPost] 
public ActionResult SaveItems(GroupModel model) 
{ 
    ... 
} 
+2

信じられません。スピード、正確さ、明快さ - StackOverflowをそのような不可欠なリソースにするのはあなたのような人たちです。どうもありがとうございます! –

関連する問題