Javascript ASP.NET MVC jQuery Ajax-从模式对话框关闭并刷新父表

Javascript ASP.NET MVC jQuery Ajax-从模式对话框关闭并刷新父表,javascript,jquery,ajax,asp.net-mvc,Javascript,Jquery,Ajax,Asp.net Mvc,MVC和jQuery都是新手,所以我不知道如何让它工作。我用ajax回发拼凑了一个(有点)工作模式对话框表单。已经搜索了两天,但没有找到优秀的MVC+jQuery示例。数据按预期插入,这只是我很难使用的UI 我有两个视图:索引和创建。索引列出了一个普通表中的所有记录,用Razor循环结果。Create是我正在加载到模式对话框中的插入表单: @model IEnumerable<MyProject.Models.StockIndex> @{ ViewBag.Title = "

MVC和jQuery都是新手,所以我不知道如何让它工作。我用ajax回发拼凑了一个(有点)工作模式对话框表单。已经搜索了两天,但没有找到优秀的MVC+jQuery示例。数据按预期插入,这只是我很难使用的UI

我有两个视图:索引和创建。索引列出了一个普通表中的所有记录,用Razor循环结果。Create是我正在加载到模式对话框中的插入表单:

@model IEnumerable<MyProject.Models.StockIndex>

@{
    ViewBag.Title = "Admin: Stock Index Home";
    Layout = "~/Views/Shared/_LayoutAdmin.cshtml";
}

<h2>View Stock Indices</h2>

<p>
    <a href="#" id="createLink">Create New</a>
    <div id="createStockIndexForm"></div>
</p>
<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Name)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Description)
        </th>
        <th></th>
    </tr>

    @foreach (var item in Model)
    {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Name)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Description)
            </td>
            <td>
                @Html.ActionLink("Edit", "Edit", new { id = item.Id }) |
                @Html.ActionLink("Details", "Details", new { id = item.Id }) |
                @Html.ActionLink("Delete", "Delete", new { id = item.Id })
            </td>
        </tr>
    }

</table>

@section Scripts {
    <script>
        $('#createLink').on('click', function () {
            $("#createStockIndexForm").dialog({
                autoOpen: true,
                position: { my: "center", at: "top+350", of: window },
                width: 600,
                resizable: false,
                title: 'Create Stock Index',
                modal: true,
                open: function () {
                    $(this).load('@Url.Action("Create", "AdminStockIndex")');
                }
            });

            return false;
        });
    </script>
}
加载到对话框中的“创建”表单(如上所示):

手动关闭模态对话框后,div将按我所希望的方式重新加载。伟大的现在,如果我能在表单发布时关闭对话框,我就可以设置了。这不起作用:

$("#createStockIndexForm").dialog("close");
Firebug报告错误:

错误:初始化前无法在对话框上调用方法; 试图调用方法“close”

模式对话框始终为空,而不是关闭

它的行为可能不正常,因为您是基于对象的对话框方法而不是对象本身创建变量的。请尝试以下方法:

if (data) {
  $("#createStockIndexForm").dialog("close");
}
其次,是否有方法通过刷新父页面上的表 ajax,没有插件

当然有,但可能需要您更改一些内容,包括关闭对话框的代码。以下是我将如何处理它:

1) 记录表应该是主索引视图中的局部视图。这样做的原因是,当我们提交表单时,我们将使用ajax选项“InsertionMode”和目标id,用表单中更新的记录表替换旧记录表

2) 我们将使用ajax选项“OnSuccess”(以及“OnFailure”来处理“Something go fail”错误),而不是在onsubmit方法中处理对话框关闭代码

下面是您的新索引视图:

@model IEnumerable<MyProject.Models.StockIndex>

@{
  ViewBag.Title = "Admin: Stock Index Home";
  Layout = "~/Views/Shared/_LayoutAdmin.cshtml";
}

<h2>View Stock Indices</h2>

<p>
  <a href="#" id="createLink">Create New</a>
  <div id="createStockIndexForm"></div>
</p>

<div id="recordsDiv">
  @Html.Partial("RecordsPartial", model)
</div>

// all your script stuff can still go at the end
@section Scripts {
<script>
  // ... other stuff that was already here ...

  function postSuccess() {
    $("#createStockIndexForm").dialog("close");
  }

  function postFailed() {
    alert("Failed to post");  // you can define your own error
  }
</script>
}
这是重复一些现有的“创建”操作。我们只需处理post数据,然后得到一个新的更新记录列表,最后将该记录列表返回到“RecordsPartial”视图,该视图将按照我们在ajax选项中的指定插入到“recordsDiv”中


非常干净和简单的解决方案。如果您有问题,请随时提问。

在主索引视图中,不要要求将创建视图插入到视图中,而是在视图加载时将其初始显示,并将其隐藏在div中:

<div id="createStockIndexForm">
  @Html.Action("Create", "AdminStockIndex")
</div>
确保将“关闭”命令指向对话框对象本身

这是我制作的一把小提琴,它向你展示了小提琴的基本原理:


因此,为了重述脚本内容,您的“创建”部分中应该没有脚本。所有脚本都进入主索引视图,正如我在本回答中所详细介绍的。

我找到了一种方法来获得我想要的一切,同时保留了“纯”jQuery Ajax方法,而不是求助于Eckert建议的MVC Ajax助手。然而,他的建议使我找到了解决办法。非常感谢

我在控制器中创建了一个PartialView:

    public ActionResult GetStockIndices()
    {
        _service = new StockIndexService();
        var data = _service.GetAll();

        return PartialView("_StockIndices", data);
    }
……及其观点:

@model IEnumerable<MyApp.Models.StockIndex>

<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Name)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Description)
        </th>
        <th></th>
    </tr>

    @foreach (var item in Model)
    {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Name)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Description)
            </td>
            <td>
                @Html.ActionLink("Edit", "Edit", new { id = item.Id }) |
                @Html.ActionLink("Details", "Details", new { id = item.Id }) |
                @Html.ActionLink("Delete", "Delete", new { id = item.Id })
            </td>
        </tr>
    }

</table>
@model IEnumerable
@DisplayNameFor(model=>model.Name)
@DisplayNameFor(model=>model.Description)
@foreach(模型中的var项目)
{
@DisplayFor(modelItem=>item.Name)
@DisplayFor(modelItem=>item.Description)
@ActionLink(“编辑”,“编辑”,新的{id=item.id})|
@ActionLink(“详细信息”,“详细信息”,新的{id=item.id})|
@ActionLink(“删除”,“删除”,新的{id=item.id})
}
然后,我更改了模式对话框脚本,以便在关闭时加载局部视图。以下是整个索引视图,供子孙后代使用:

@model IEnumerable<MyApp.Models.StockIndex>

@{
    ViewBag.Title = "Admin: Stock Index Home";
    Layout = "~/Views/Shared/_LayoutAdmin.cshtml";
}

<h2>View Stock Indices</h2>

<p>
    <a href="#" id="createLink">Create New</a>
    <div id="createStockIndexForm"></div>
</p>
<div id="stockIndices">
    @Html.Partial("_StockIndices", Model)
</div>

@section Scripts {
    <script>
        var _dialog;

        $('#createLink').on('click', function () {
            _dialog = $("#createStockIndexForm").dialog({
                autoOpen: true,
                position: { my: "center", at: "top+400", of: window },
                width: 600,
                resizable: false,
                title: 'Create Stock Index',
                modal: true,
                open: function () {
                    $(this).load('@Url.Action("Create", "AdminStockIndex")');
                },
                close: function () {
                    $("#stockIndices").load('@Url.Action("GetStockIndices", "AdminStockIndex")');
                }
            });

            return false;
        });
    </script>
}
@model IEnumerable
@{
ViewBag.Title=“管理员:股票指数主页”;
Layout=“~/Views/Shared/\u LayoutAdmin.cshtml”;
}
查看股票指数

@Html.部分(“_股票指数”,模型) @节脚本{ var_对话框; $('#createLink')。在('click',函数(){ _dialog=$(“#createStockIndexForm”)。dialog({ 自动打开:对, 位置:{my:“center”,在“top+400”,of:window}, 宽度:600, 可调整大小:false, 标题:“创建股票指数”, 莫代尔:是的, 打开:函数(){ $(this.load('@Url.Action(“Create”,“AdminStockIndex”)); }, 关闭:函数(){ $(“#股票指数”).load('@Url.Action(“GetStockIndex”,“AdminStockIndex”)); } }); 返回false; }); }
请注意全局“\u dialog”变量。这使我可以从创建窗体访问该对话框,因此可以关闭该对话框:

<script>
    $("#createForm").on("submit", function (event) {
        event.preventDefault();

        $.ajax({
            url: this.action,
            type: this.method,
            async: true,
            data: $(this).serialize(),
            success: function (data) {
                if (data) {
                    if (_dialog) {
                        _dialog.dialog("close");
                    }
                }
                else {
                    $("#result").append("Error! Record could not be added.");
                }
            },
            error: function (error) {
                console.error(error);
            }
        });
    });
</script>

$(“#createForm”)。在(“提交”上,函数(事件){
event.preventDefault();
$.ajax({
url:this.action,
类型:this.method,
async:true,
数据:$(this).serialize(),
成功:功能(数据){
如果(数据){
如果(_对话框){
_dialog.dialog(“关闭”);
}
}
否则{
$(“#结果”).append(“错误!无法添加记录”);
}
},
错误:函数(错误){
控制台错误(error);
}
});
});

谢谢@Eckert。当我尝试按照您的建议关闭对话框时,会出现错误“错误:初始化之前无法调用对话框上的方法;尝试调用方法“close””——这就是我尝试首先初始化它的原因。我会把你的片面观点和错误的观点弄得一团糟
@section Scripts {
<script>
  // ... other stuff that was already here ...

  function postSuccess() {
    $("#createStockIndexForm").dialog("close");
  }

  function postFailed() {
    alert("Failed to post");  // you can define your own error
  }
</script>
}
[HttpPost]
public ActionResult CreateRecord(StockIndexEditViewModel model)
{
  if (ModelState.IsValid)
  {
    ... create record here ...
  }

  var records = db.Indexes.ToList(); // or whatever your table name is

  return PartialView("RecordsPartial", records);
}
<div id="createStockIndexForm">
  @Html.Action("Create", "AdminStockIndex")
</div>
@section Scripts {
<script>
    $("#createStockIndexForm").dialog({
            autoOpen: false,
            position: { my: "center", at: "top+350", of: window },
            width: 600,
            resizable: false,
            title: 'Create Stock Index',
            modal: true
    });

    $('#createLink').on('click', function () {
        $("#createStockIndexForm").show();
    });
</script>
<input type="button" id="createButton" value="Create" class="btn btn-default" />
$("#createButton").on("click", function () {

        $.ajax({
            url: this.action,
            type: this.method,
            async: true,
            data: $(this).serialize(),
            success: function (data) {
                if (data) {
                    $("#createStockIndexForm").dialog("close");
                }
                else {
                    $("#result").append("Something went fail.");
                }
            }
        });
    });
    public ActionResult GetStockIndices()
    {
        _service = new StockIndexService();
        var data = _service.GetAll();

        return PartialView("_StockIndices", data);
    }
@model IEnumerable<MyApp.Models.StockIndex>

<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Name)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Description)
        </th>
        <th></th>
    </tr>

    @foreach (var item in Model)
    {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Name)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Description)
            </td>
            <td>
                @Html.ActionLink("Edit", "Edit", new { id = item.Id }) |
                @Html.ActionLink("Details", "Details", new { id = item.Id }) |
                @Html.ActionLink("Delete", "Delete", new { id = item.Id })
            </td>
        </tr>
    }

</table>
@model IEnumerable<MyApp.Models.StockIndex>

@{
    ViewBag.Title = "Admin: Stock Index Home";
    Layout = "~/Views/Shared/_LayoutAdmin.cshtml";
}

<h2>View Stock Indices</h2>

<p>
    <a href="#" id="createLink">Create New</a>
    <div id="createStockIndexForm"></div>
</p>
<div id="stockIndices">
    @Html.Partial("_StockIndices", Model)
</div>

@section Scripts {
    <script>
        var _dialog;

        $('#createLink').on('click', function () {
            _dialog = $("#createStockIndexForm").dialog({
                autoOpen: true,
                position: { my: "center", at: "top+400", of: window },
                width: 600,
                resizable: false,
                title: 'Create Stock Index',
                modal: true,
                open: function () {
                    $(this).load('@Url.Action("Create", "AdminStockIndex")');
                },
                close: function () {
                    $("#stockIndices").load('@Url.Action("GetStockIndices", "AdminStockIndex")');
                }
            });

            return false;
        });
    </script>
}
<script>
    $("#createForm").on("submit", function (event) {
        event.preventDefault();

        $.ajax({
            url: this.action,
            type: this.method,
            async: true,
            data: $(this).serialize(),
            success: function (data) {
                if (data) {
                    if (_dialog) {
                        _dialog.dialog("close");
                    }
                }
                else {
                    $("#result").append("Error! Record could not be added.");
                }
            },
            error: function (error) {
                console.error(error);
            }
        });
    });
</script>