【发布时间】:2016-05-30 15:02:58
【问题描述】:
我正在使用 AJAX 将引导模式内容替换为这样的部分视图:
主视图 HTML
<div class="container row form-horizontal">
<div id="myModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content" id="myModalContent">
</div>
</div>
</div>
</div>
主视图内的 AJAX 脚本
$(function () {
$.ajaxSetup({ cache: false });
$(document).on('click', 'a[data-modal]', function (e) {
$('#myModalContent').load(this.href, function () {
$('#myModal').modal({
keyboard: true
}, 'show');
bindForm(this);
$("form").removeData("validator");
$("form").removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse("form");
});
return false;
});
});
function bindForm(dialog) {
$('form', dialog).submit(function () {
$('#progress').show();
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result) {
if (result.success) {
$('#myModal').modal('hide');
$('#progress').hide();
alert('reloading');
location.reload();
} else {
$('#progress').hide();
$('#myModalContent').html(result);
bindForm();
}
}
});
return false;
});
}
部分视图 HTML
@model MVC_Replica.Models.Location
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 class="modal-title">Add New Location</h3>
</div>
@using (Html.BeginForm("Create","Locations",FormMethod.Post))
{
@Html.AntiForgeryToken()
<div class="modal-body">
<div class="form-horizontal">
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.LocationName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.LocationName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.LocationName, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.DateCreated, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.DateCreated, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.DateCreated, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.LocationState, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.LocationState, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.LocationState, "", new { @class = "text-danger" })
</div>
</div>
</div>
</div>
<div class="modal-footer">
<span id="progress" class="text-center" style="display: none;">
<img src="~/media/ajax-loading.gif" alt="wiat" />
Wait..
</span>
<input type="submit" class="btn btn-primary pull-left" value="Create" />
<button class="btn btn-warning" data-dismiss="modal">Close</button>
</div>
}
结果
模式正确打开,客户端验证运行良好。但是,当我submitpartial view 时,永远不会执行以下控制器操作:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Location location)
{
if (ModelState.IsValid)
{
location.DateCreated = DateTime.Now;
db.Locations.Add(location);
db.SaveChanges();
return Json(new { success = true });
}
return PartialView("_CreateLocation", location);
}
我尝试在ModelState.IsValid 旁边放置一个刹车点,但它永远不会被击中。另外,浏览器控制台也没有显示任何错误
可能是什么问题?
编辑
通过将anchor href 值存储在global variable 中并更改bindForm 函数,我设法让局部视图调用创建操作控制器:
var actionUrl;
$(function () {
$('form').submit(function () {
// alert(this.action);
});
$.ajaxSetup({ cache: false });
$(document).on('click', 'a[data-modal]', function (e) {
actionUrl = this.href;
$('#myModalContent').load(this.href, function () {
$('#myModal').modal({
keyboard: true
}, 'show');
bindForm();
$("form").removeData("validator");
$("form").removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse("form");
});
return false;
});
});
function bindForm() {
$('form').on('submit',function () {
$('#progress').show();
$.ajax({
url: actionUrl,
type: 'POST',
data: $(this).serialize(),
success: function (result) {
if (result.success) {
$('#myModal').modal('hide');
$('#progress').hide();
location.reload();
} else {
$('#progress').hide();
$('#myModalContent').html(result);
bindForm();
}
}
});
return false;
});
}
【问题讨论】:
-
会发生什么?在最坏的情况下,表单应该尝试以传统方式发布,而不使用 AJAX,因此页面应该更改为 something。如果您的 AJAX 工作正常,那么您一定会收到某种响应,即使它只是 404 或 500。在浏览器的开发控制台中查找 AJAX 请求并检查响应。
-
嗨,克里斯,发生了回发,并调用了我的主视图 HttpGet 操作结果
-
默认情况下,操作同时接受 GET 和 POST。这意味着您的问题有两个方面:1)错误的 URL 被发布到和 2)表单以传统方式发布,而不是通过 AJAX。首先,您需要检查您的路由并查看上面有什么。其次,您可能需要使用委托,因为 JavaScript 代码在被替换后可能不会应用于新的表单代码。
-
我注意到 bindForm 函数没有被执行。我尝试使用“on”委托而不是 bindFunction().sumbit,我得到了相同的结果。但是,一旦我删除了 bidnForm 函数中的对话框选择器,它就会正确执行 AJAX 调用,但会调用索引操作结果而不是所需的创建操作。所以我想我有一个额外的线索来解决这个问题。有什么想法吗?
-
通过委托,我的意思是您需要绑定到永远不会被替换的表单的父元素,并通过选择器将其“委托”到表单。例如,
$('#myModalContent').on('submit', 'form', function () { /* do something * });之类的东西。换句话说,您将绑定到这个不会更改的 div,并让它将任何提交事件委托给它在事件发生时找到的任何表单元素。
标签: jquery ajax asp.net-mvc twitter-bootstrap partial-views