MVC 5局部视图异步回发

时间:2015-08-04 19:42:01

标签: asp.net-mvc

我有一种Master-Detail Edit表单,我试图关注这篇文章:Using Ajax...以获得部分回发的视图。

我的“编辑”表单包含一个部分视图,其中包含一个子项列表,另一个部分创建视图用于添加新项目。我希望部分创建视图能够在不刷新整个页面的情况下回发和更新列表。

这是我到目前为止所拥有的:

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>

编辑:我重写了页面,以便列表是创建局部视图的一部分。现在发生的是,如果您输入_CustomFieldCreate的数据并按下提交,则第一次只刷新该视图(包括嵌套列表视图)。然而,第二次,它重定向到视图,可能是因为第一次刷新没有将javascript重新绑定到提交按钮。此外,“创建”视图不会清除字段,但会保留最初输入的数据。

2 个答案:

答案 0 :(得分:0)

您需要在局部视图中使用一个表单,其提交操作会绑定到发布到控制器的javascript函数。

例如,如果您的表单ID是MyForm:

 $('#MyForm').on('submit', function (e) {
    e.preventDefault(); //This prevent the regular form submit
    $.ajax({
        url: $(this).action, // This will submit the post to whatever action your form goes to
        type: "POST", // This tells it that it is a post
        data: $(this).serialize(), // This sends the data in the form to the controller
        success: function (data) {
            // do some javascript on success
        },
        error: function (xhr, ajaxOptions, thrownError) {
            // do some javascript on error
        }
    });
});

此javascript会覆盖默认表单提交,并向您的控制器发送ajax帖子,然后返回成功或错误,您可以执行任何操作。

这是一些jquery ajax文档:

http://api.jquery.com/jquery.ajax/

答案 1 :(得分:0)

你应该考虑使用AJAX。这应该完成我认为你所描述的。您将需要创建一个javascript函数来处理表单上的提交事件,然后使用AJAX将表单数据发布到MVC应用程序中的某些创建操作。如果您使用的是jQuery,那么库就非常简单。 http://api.jquery.com/jquery.ajax/