动态创建的局部视图不会在提交时调用控制器操作
Dynamically created Partial View does not call controller action on submit
我正在使用 AJAX 将 bootstrap 模态内容替换为这样的局部视图:
主视图 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>
}
结果
模式打开正确,客户端验证工作得很好。但是,当我 submit
partial 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
旁边放置一个制动点,但它永远不会 hit.Also 浏览器控制台未显示任何错误
可能是什么问题?
编辑
我通过将 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;
});
}
所以 create controller action
从未被调用的原因是因为 bindForm
函数的 submit
事件从未被执行。正如我所发现的,bindForm
函数中的 dialog
selector
阻止了事件的触发。我对问题进行了编辑,解释了可能的解决方案。
我正在使用 AJAX 将 bootstrap 模态内容替换为这样的局部视图:
主视图 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>
}
结果
模式打开正确,客户端验证工作得很好。但是,当我 submit
partial 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
旁边放置一个制动点,但它永远不会 hit.Also 浏览器控制台未显示任何错误
可能是什么问题?
编辑
我通过将 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;
});
}
所以 create controller action
从未被调用的原因是因为 bindForm
函数的 submit
事件从未被执行。正如我所发现的,bindForm
函数中的 dialog
selector
阻止了事件的触发。我对问题进行了编辑,解释了可能的解决方案。