Начнем с того, что вам нужно помнить, что ModelBinder по умолчанию является рекурсивным, и он попытается решить, что ему нужно сделать ... так что это довольно умно.Еще одна вещь, которую нужно помнить, это то, что вам не нужно , чтобы использовать помощники html, фактический html также отлично работает: -)
Итак, во-первых, с моделью, здесь ничего не отличается ...
public class ParentViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public List<ChildViewModel> Child { get; set; }
}
public class ChildViewModel
{
public int Id { get; set; }
public string FirstName { get; set; }
}
Родительское частичное представление - это принимает экземпляр ParentViewModel
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<ParentViewModel>" %>
<h2>Parent</h2>
<%: Html.TextBox("parent.Name", Model.Name) %>
<%: Html.Hidden("parent.Id", Model.Id) %>
<% foreach (ChildViewModel childViewModel in Model.Child)
{
Html.RenderPartial("Child", childViewModel);
}
%>
Дочернее частичное представление - это принимает один экземпляр ChildViewModel
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<ChildViewModel>" %>
<h3>Child</h3>
<%: Html.Hidden("parent.Child.index", Model.Id) %>
<%: Html.Hidden(string.Format("parent.Child[{0}].Id", Model.Id), Model.Id)%>
<%: Html.TextBox(string.Format("parent.Child[{0}].FirstName", Model.Id), Model.FirstName) %>
В этой точке следует отметить, что значение индекса - это то, что используется для обработки уникальной записи в списке.Это не обязательно должно быть инкрементное значение.
Итак, как вы это называете?Хорошо в действии Index, которое будет отображать данные, которые необходимо передать. Я настроил некоторые демонстрационные данные и вернул их в словарь ViewData для представления индекса.
Итак, действие контроллера ...
public ActionResult Index()
{
ViewData["Message"] = "Welcome to ASP.NET MVC!";
ViewData["Parent"] = GetData();
return View();
}
private ParentViewModel GetData()
{
var result = new ParentViewModel
{
Id = 1,
Name = "Parent name",
Child = new List<ChildViewModel>
{
new ChildViewModel {Id = 2, FirstName = "first child"},
new ChildViewModel {Id = 3, FirstName = "second child"}
}
};
return result;
}
В реальном мире вы вызываете службу данных и т. Д.
И, наконец, содержимое представления индекса:
<form action="<%: Url.Action("Edit") %>" method="post">
<% if (ViewData["Parent"] != null) { %>
<%
Html.RenderPartial("Parent", ViewData["Parent"]); %>
<% } %>
<input type="submit" />
</form>
Сохранение
Итак, теперь у нас есть данные, отображаемые как мы можем вернуть их в действие?Что ж, это то, что механизм связывания моделей по умолчанию сделает для вас на простых типах данных в относительно сложных формациях.Таким образом, вы можете установить основной формат действия, которое вы хотите опубликовать как:
[HttpPost]
public ActionResult Edit(ParentViewModel parent)
{
}
Это даст вам обновленные данные с оригинальными идентификаторами (из скрытых полей), чтобы вы могли обновлять / редактироватьпри необходимости.
Новые дети через Ajax
Вы упоминали в своем вопросе о загрузке пользовательских шаблонов через ajax, вы имеете в виду, как дать пользователю возможность добавлять вдругой ребенок без обратной передачи?
Если это так, вы делаете что-то вроде этого ...
Добавить действие - Нужно действие, которое возвратит новую ChildViewModel
[HttpPost]
public ActionResult Add()
{
var result = new ChildViewModel();
result.Id = 4;
result.FirstName = "** to update **";
return View("Child", result);
}
Я дал ему идентификатор для простых демонстрационных целей.
Затем вам понадобится способ вызова кода, поэтому единственное представление, которое вам нужно обновить, - это главное представление Index.Это будет включать JavaScript, чтобы получить результат действия, ссылку для вызова кода и целевой HTML-тег для HTML, который будет добавлен.Также не забудьте добавить ссылку на jQuery на главной странице или в верхней части представления.
Представление указателя - обновлено!
<script type="text/javascript">
function add() {
$.ajax(
{
type: "POST",
url: "<%: Url.Action("Add", "Home") %>",
success: function(result) {
$('#newchild').after(result);
},
error: function(req, status, error) {
}
});
}
</script>
<form action="<%: Url.Action("Edit") %>" method="post">
<% if (ViewData["Parent"] != null) { %>
<%
Html.RenderPartial("Parent", ViewData["Parent"]); %>
<% } %>
<div id="newchild"></div>
<br /><br />
<input type="submit" /> <a href="#" onclick="JavaScript:return add();">add child</a>
</form>
Этовызовет действие add и добавит ответ, когда он вернется в div newChild над кнопкой отправки.
Надеюсь, длинный пост полезен.
Наслаждайтесь: -)