У меня есть вид формы редактирования Master-Detail, и я стараюсь следить за этим сообщением: Using Ajax..., чтобы получить частичный вид обратной передачи.MVC 5 частичный вид async postback
В моей форме редактирования есть частичный вид, который имеет список подпунктов, а другой частичный вид создания в нем для добавления новых элементов. Мне хотелось бы, чтобы частичное представление было опубликовано и обновлено, не обновляя всю страницу, если это возможно.
Вот что я до сих пор:
MyController.cs -
public ActionResult Edit(int? id)
{
//...
ViewBag.CustomFormId = id;
using (var _db = new MkpContext())
{
//...
return View(profileEdit);
}
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(CustomForm editForm)
{
//...
if (!ModelState.IsValid) return View(editForm);
using (var _db = new MkpContext())
{
var form = _db.CustomForms.Find(editForm.CustomFormId);
//...
_db.Entry(form).State = EntityState.Modified;
_db.SaveChanges(User.ProfileId);
return RedirectToAction("Index");
}
}
public ActionResult _CustomFieldList(int id)
{
ViewBag.CustomFormId = id;
using (var _db = new MkpContext())
{
var formCustomFields = (from cf in _db.CustomFields
where cf.CustomFormId == id
select cf);
return PartialView(formCustomFields.ToList());
}
}
// Nested in _CustomFieldList
public ActionResult _CustomFieldCreate(int id)
{
var newField = new CustomField
{
CustomFormId = id
};
return PartialView(newField);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult _CustomFieldCreate(CustomField addField)
{
ViewBag.CustomFormId = addField.CustomFormId;
if (ModelState.IsValid)
{
using (var _db = new MkpContext())
{
_db.CustomFields.Add(addField);
_db.SaveChanges();
}
var newField = new CustomField
{
CustomFormId = addField.CustomFormId
};
return PartialView(newField); // Probably need to change this somehow
}
return PartialView(addField);
}
И взгляды:
Edit.cshtml -
@model PublicationSystem.Model.CustomForm
@{
ViewBag.Title = "Edit Custom Form";
Layout = "~/Views/Shared/_LayoutSmBanner.cshtml";
}
<div class="form-horizontal">
<div class="row">
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@* Fields for this form *@
}
<div id="CustomFields" class="col-md-6">
@Html.Action("_CustomFieldCreate", new { id = ViewBag.CustomFormId })
</div>
</div>
</div>
<script>
$(function() {
$("#createFieldForm").on("submit", function (e) {
e.preventDefault(); //This prevent the regular form submit
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result) {
$("#CustomFields").html(result);
}
});
return false;
});
});
</script>
_CustomFieldCreate.cshtml -
@model PublicationSystem.Model.CustomField
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div id="result"></div>
<div class="form-horizontal">
<h4>CustomField</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model =>model.CustomFormId)
<div class="row">
@* Fields for the form *@
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div id="customFieldList">
@Html.Action("_CustomFieldList", new { id = ViewBag.CustomFormId })
</div>
_CustomFieldList.cshtml
@model System.Collections.Generic.IEnumerable<PublicationSystem.Model.CustomField>
<table class="table">
@* List table code *@
</table>
Edit: я переписал страницы так, что список является частью создания частичного вида. Что происходит сейчас, если вы вводите данные для _CustomFieldCreate и нажимаете submit, в первый раз он обновляет только этот вид (включая представление вложенного списка). Однако во второй раз он перенаправляет на представление, вероятно, потому, что первое обновление не переустанавливало javascript на кнопку отправки. Кроме того, представление Create не очищает поля, но сохраняет исходно введенные данные.