私はMVC Webアプリケーションで作業しており、可変長の項目リストを持つ必要があります。ユーザーは、すべての行に対してバッチ更新を行う保存で行を追加/編集および削除できる必要があります。MVCの項目の可変長リストを編集する
私は仕事のほとんどをカバーしていた2つのブログ投稿から作業を始めました。そのため、スティーブ・サンダーソンのすべての信用を得ました。
Editing a variable-length list of items in ASP.NET MVC
私は
<% using (Html.BeginForm()) { %>
<div id="placeholder">
<% for (int i = 0; i < Model.Count(); i++)
{
ViewData["index"] = i;
Html.RenderPartial("ProfileItemLine", Model.ElementAt(i), new ViewDataDictionary(ViewData) {
{"prefix", "items"}
});
}
%>
</div>
<div id="addProfileItem">
<a href="" id="addItem">Add another item</a>
</div>
<input type="submit" value="Save changes" />
<% } %>
を次のように私の見解を持っており、追加を処理するためのjQueryを使用して
$(document).ready(function() {
var nextIndex = <%=ViewData.Model.Count()%>;
setRemoveLinks();
$('#addItem').click(function() {
var action = '/Profile/BlankItemLine?index=' + nextIndex;
$.get(action, 'html', function(lineItemHtml) {
$('#placeholder').append(lineItemHtml);
setRemoveLinks();
});
nextIndex++;
return false;
});
});
function setRemoveLinks() {
$('a.removeItem').click(function() {
$(this).parent('div').remove();
return false;
});
}
マイナスのフォーマットとプレーンテキスト
を次のようにProfileItemLine ViewUserControlがあるが削除されます<div>
<% var fieldPrefix = string.Format("{0}[{1}].", ViewData["prefix"], ViewData.Model.Sequence); %>
<%= Html.Hidden(fieldPrefix + "ProfileItemId", ViewData.Model.ProfileItemId)%>
<%= Html.TextBox(fieldPrefix + "Title", ViewData.Model.Title, new { size = "30"})%>
<%= Html.CheckBox(fieldPrefix + "IsHighlighted", ViewData.Model.IsHighlighted)%>
<a href="" class="removeItem">Delete</a></div>
これまでのところ、リストはモデルに正しくバインドされていて、アイテムを追加するだけで動作します。
問題は削除に関連しています。削除が機能し、正しい行が削除されますが、フォームの送信時にすべてのバインディングが失われます。スティーブのポストでは、モデルバインドの仕方がRCによって変更され、すべてのインデックスが途切れのない昇順であることが必要であると述べています。
スティーブはフォーム提出時にリストを並べ替える作業を行うためにいくつかのコードを列挙しましたが、サポートされていないメソッドでは "var controls ="行に例外がスローされます。この例ではIのみバック最初の項目を取得しない形で
$(function() {
$("form").submit(function() {
// Normalize the sequence before submitting the form
ensureControlGroupsInNumericalOrder("#placeholder div", "items");
});});
function ensureControlGroupsInNumericalOrder(groupSelector, controlNamePrefix) {
var groups = $(groupSelector);
var nameToEndOfIndexRegex = new RegExp(controlNamePrefix + "\\[\\d+");
for (var seq = 0; seq < groups.length; seq++) {
var controls = $("*[name~=" + controlNamePrefix + "\[]", groups[seq]);
for (var c = 0; c < controls.length; c++)
controls[c].name = controls[c].name.replace(nameToEndOfIndexRegex, controlNamePrefix + "[" + seq);
}}
ふたつのインデックスの削除1及び2
<div id="placeholder">
<div>
<input id="items[0]_ProfileItemId" name="items[0].ProfileItemId" type="hidden" value="0fd3a3f5-907e-4eb1-8f69-26e3840e5e12" />
<input id="items[0]_Title" name="items[0].Title" size="30" type="text" value="Number 1" />
<input id="items[0]_IsHighlighted" name="items[0].IsHighlighted" type="checkbox" value="true" />
<input name="items[0].IsHighlighted" type="hidden" value="false" />
<a href="" class="removeItem">Delete</a>
</div>
<div>
<input id="items[3]_ProfileItemId" name="items[3].ProfileItemId" type="hidden" value="0fa1a3f5-907e-4eb1-8f69-26e3840e5e12" />
<input id="items[3]_Title" name="items[3].Title" size="30" type="text" value="Number 3" />
<input id="items[3]_IsHighlighted" name="items[3].IsHighlighted" type="checkbox" value="true" />
<input name="items[3].IsHighlighted" type="hidden" value="false" />
<a href="" class="removeItem">Delete</a>
</div>
</div>
Iモデルバインド後のHTML出力の例をIEnumerableをには、送信、それはアイテム1ではなく、アイテム[3]であるためです。
public ActionResult EditItems(Guid id, IEnumerable<ProfileItem> items)
{
if (ModelState.IsValid)
{
// Save items
}
if (ModelState.IsValid)
return RedirectToAction("Index");
else
return View(items);
}
私はまだ誰もが解決策に私を指すことができれば私は疑問に思うjQueryと正規表現に自分の歯をカットしています。
ありがとうございます。
こんにちは、 これは私のシナリオでは機能しますか?私は、個々の要素情報が、リストへのモデルバインディングに関連していると思います。 http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspxを参照してください。 私の要件は、DBへの個々の呼び出しが発生しないようにバッチ操作を行うことです。だからまだ私はあなたのソリューションを試してみましたが、私はこれが答えであるかどうかはわかりません。あなたは実践的な例を持っていますか? –