我一直在這個問題上撞了我的頭幾天,現在無法弄清楚。我需要創建一個允許用戶添加和刪除複雜分層對象的視圖。假例如:我可以使用添加/刪除功能顯示MVC 4視圖中的複雜對象列表嗎?
模式
public class ParentModel
{
public int ParentId { get; set; }
public string ParentText { get; set; }
public IList<ChildModel> Children { get; set; }
}
public class ChildModel
{
public int ChildId { get; set; }
public string ChildText { get; set; }
public IList<GrandChildModel> GrandChildren { get; set; }
}
public class GrandChildModel
{
public int GrandChildId { get; set; }
public string GrandChildText { get; set; }
}
現在,假設我有填充一個ParentModel
的動作和它的子屬性,一個簡單的觀點看起來是這樣的:
@model EditorTemplateCollectiosns.Models.ParentModel
@using (@Html.BeginForm())
{
<div>
@Html.TextBoxFor(m => m.ParentId)
@Html.TextBoxFor(m => m.ParentText)<br/>
Children:<br/>
@for (var i = 0; i < Model.Children.Count; i++)
{
@Html.TextBoxFor(m => Model.Children[i].ChildId)
@Html.TextBoxFor(m => Model.Children[i].ChildText)
<div>
Grandchildren:<br/>
<table id="grandChildren">
<tbody>
@for (var j = 0; j < Model.Children[i].GrandChildren.Count; j++)
{
<tr>
<td>@Html.TextBoxFor(m => @Model.Children[i].GrandChildren[j].GrandChildId)</td>
<td>@Html.TextBoxFor(m => @Model.Children[i].GrandChildren[j].GrandChildText)</td>
</tr>
}
</tbody>
</table>
</div>
}
</div>
<button type="button" id="addGrandchild">Add Grandchild</button>
<input type="submit" value="submit"/>
}
<script type="text/javascript">
$(document).ready(function() {
$("#addGrandchild").click(function() {
$("#grandChildren tbody:last").append('<tr><td><input type="text" name="grandChildId" /></td><td><input type="text" name="grandChildText" /></td></tr>');
});
});
</script>
這種觀點除非我添加孫子並提交表單,否則它不會與GrandChildModel
列表綁定。在POST的小提琴:
所以我試圖用一個編輯模板GrandChildModel
,只是爲了看看它是否會工作。這個功能很好地簡單地顯示對象,但我不知道如何將一個孫子添加到列表中並讓它顯示在編輯器模板中。我也嘗試嵌入部分視圖加載$.ajax
調用,但這變成了一個後勤噩夢。
在實際的應用程序中,層次結構比這個例子更深,並且每個連續的子對象都需要具有這種添加/刪除功能。每次用戶想要添加或刪除一個對象時,甚至可能沒有表單的完整文章?通過上面示例中的方法,是否可以在POST上將新添加的孫子女綁定到IList
?或者,有沒有辦法在客戶端添加對象,並在編輯器模板和上綁定到POST上的IList
?如果兩種選擇都不是正確的方法,那是什麼?
UPDATE
我已經想通了的東西哈克可能的工作,但我還是很想知道,如果有這樣做的更簡單的方法。我將上面的視圖代碼更改爲:
@model EditorTemplateCollectiosns.Models.ParentModel
@using (@Html.BeginForm())
{
<div>
@Html.TextBoxFor(m => m.ParentId)
@Html.TextBoxFor(m => m.ParentText)<br/>
Children:<br/>
<button type="button" id="addChild" onclick="addChildRow()">Add Child</button>
<table id="children">
<tbody class="childTableBody">
@for (var i = 0; i < Model.Children.Count; i++)
{
<tr>
<td colspan="3">Child @i</td>
</tr>
<tr class="childInfoRow">
<td>
@Html.TextBoxFor(m => Model.Children[i].ChildId)
</td>
<td>
@Html.TextBoxFor(m => Model.Children[i].ChildText)
</td>
<td>
<button type="button" id="[email protected](i)" onclick="removeChildRow(this)">Delete</button>
</td>
</tr>
<tr>
<td colspan="3">
Grandchildren:<br/>
<button type="button" id="[email protected](i)" onclick="addGrandchildRow(this)">Add Grandchild</button>
<table id="[email protected](i)">
<tbody>
@for (var j = 0; j < Model.Children[i].GrandChildren.Count; j++)
{
<tr>
<td>@Html.TextBoxFor(m => @Model.Children[i].GrandChildren[j].GrandChildId)</td>
<td>@Html.TextBoxFor(m => @Model.Children[i].GrandChildren[j].GrandChildText)</td>
<td><button type="button" id="[email protected](i)[email protected](j)" onclick="removeGrandchildRow(this)">Delete</button></td>
</tr>
}
</tbody>
</table>
</td>
</tr>
}
</tbody>
</table>
</div>
<input type="submit" value="submit"/>
}
然後,我添加了以下javascript。我不能使用類和jQuery click事件處理程序重新綁定的處理程序後,各添加/刪除似乎不工作的權利:
<script type="text/javascript">
function addChildRow() {
var newRowIndex = $("#children tr.childInfoRow").length;
var newRow = '<tr><td colspan="3">Child ' + newRowIndex + '</td></tr><tr class="childInfoRow"><td><input type="text" name="Children[' + newRowIndex + '].ChildId" /></td>' +
'<td><input type="text" name="Children[' + newRowIndex + '].ChildText" /></td>' +
'<td><button type="button" id="removeChild' + newRowIndex + '" onclick="removeChildRow(this)">Delete</button></td></tr>' +
'<td colspan="3">Grandchildren: <br/><button type="button" id="addGrandchild' + newRowIndex + '" onclick="addGrandchildRow(this)">Add Grandchild</button>' +
'<table id="grandChildren' + newRowIndex + '"><tbody></tbody></table></td></tr>';
$("#children tbody.childTableBody:last").append(newRow);
}
function addGrandchildRow(elem) {
var childIndex = $(elem).attr('id').replace('addGrandchild', '');
var newRowIndex = $("#grandChildren" + childIndex + " tr").length;
var newRow = '<tr><td><input type="text" name="Children[' + childIndex + '].GrandChildren[' + newRowIndex + '].GrandChildId" /></td>' +
'<td><input type="text" name="Children[' + childIndex + '].GrandChildren[' + newRowIndex + '].GrandChildText" /></td>' +
'<td><button type="button" id="removeGrandchild' + childIndex + '_' + newRowIndex + '" onclick="removeGrandchildRow(this)">Delete</button></td></tr>';
$("#grandChildren" + childIndex + " tbody:last").append(newRow);
}
function removeChildRow(elem) {
$(elem).closest('tr').prev().remove();
$(elem).closest('tr').next().remove();
$(elem).closest('tr').remove();
}
function removeGrandchildRow(elem) {
$(elem).closest('tr').remove();
}
</script>
到目前爲止,這是工作,並且陣列價值觀似乎正確地綁定。然而,我並不是要將大量行添加到任何表中的大量東西的巨大粉絲。有沒有人有更好的主意?
我會在一兩分鐘 – amhed 2013-04-07 14:23:15
我不關心庫代碼的更新一個例子,但是我專注如何以允許添加和刪除從層次結構的項目顯示它。更多的視圖/控制器的東西比數據訪問/存儲庫。 – 2013-04-08 14:19:32
是否需要同時向控制器發送多個項目?因爲我認爲使用AJAX一對一添加新項目會更容易。我可以發佈一個例子,如果你想:) – amhed 2013-04-08 19:05:44