如何正确使用带有 Ajax Begin 表单的局部视图
Posted
技术标签:
【中文标题】如何正确使用带有 Ajax Begin 表单的局部视图【英文标题】:How to correctly use Partial views with Ajax Begin form 【发布时间】:2016-05-02 09:49:14 【问题描述】:我的 index.cshtml 中有以下代码
@using Kendo.Mvc.UI;
@using xx.Relacionamiento.Modelo.Bussiness.Entities;
@using xx.Relacionamiento.Modelo.Bussiness.Entities.Custom;
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
<script src="~/Scripts/jquery.validate.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
@model PresupuestosGenerale
@
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
<div class="">
<div id="ContenedorPresupuestoGeneral">
@Html.Partial("CreateOrEditPresupuestoGeneralxx", Model)
</div>
<br />
<br />
然后我有以下PartialView
@using xx.Relacionamiento.Modelo.Bussiness.Entities.Enumeraciones;
@using xx.Relacionamiento.Modelo.Bussiness.Entities;
@using Kendo.Mvc.UI;
@model PresupuestosGenerale
<div class="panel panel-default">
<div class="panel-heading">
@using (Ajax.BeginForm("CreateOrEditPresupuestoGeneralxx", new AjaxOptions() HttpMethod = "Post", UpdateTargetId = "ContenedorPresupuestoGeneral", InsertionMode = InsertionMode.Replace ))
@Html.HiddenFor(h => h.PresupuestoGeneralId)
@Html.Hidden("Categoria",CategoriaEvento.xx.ToString())
<div class="row">
<div class="col-lg-6 col-md-6 col-sm-6 col-xs-6">
<label>Presupuesto Global xx</label>
<br />
@(Html.Kendo().NumericTextBoxFor(e => e.PresupuestoGlobal)
.Decimals(0)
.DecreaseButtonTitle("Decrementar")
.IncreaseButtonTitle("Incrementar")
.Format("c0")
.HtmlAttributes(new style = "width:99%;" )
.Max(1000000000000000000)
.Min(1)
.Step(100000)
.Placeholder("Presupuesto General xx"))
@Html.ValidationMessageFor(v => v.Valor, "", new @style = "color: rgba(247, 20, 10, 0.97);" )
</div>
<div class="col-md-3">
<br />
<input type="submit" class="form-control btn btn-primary" value="Guardar Presupuesto" onclick="SetMostrarVentana();" />
</div>
</div>
</div>
</div>
<script type="text/javascript">
$(function ()
MostrarVentanaLoading = false;
@if (!string.IsNullOrEmpty(ViewBag.MensajeError))
@:mostrarMensajeAlertGlobal("@ViewBag.MensajeError",15000)
else if (!string.IsNullOrEmpty(ViewBag.MensajeSuccess))
@:mostrarMensajeAlertSuccessGlobal("@ViewBag.MensajeSuccess", 15000);
);
</script>
然后在我的控制器上,我的业务逻辑会根据条件返回不同的内容
public ActionResult CreateOrEditPresupuestoGeneralxx(PresupuestosGenerale presupuestoGeneralxx)
try
ModelState.Remove("PresupuestoGlobal");
if (presupuestoGeneralxx == null)
return PartialView();
if (!ModelState.IsValid)
return PartialView(presupuestoGeneraxx);
if (presupuestoGeneralxx.Valor < 1)
ModelState.AddModelError("Valor", "Por favor ingrese un presupuesto total");
return PartialView(presupuestoGeneralxx);
因此,当用户提交表单时,索引视图中的容器将替换为新的 html。
代码运行良好,但是我觉得代码很丑,不可维护且难以阅读。
我的问题是,对于 asp.net mvc 和 ajax,是否有更好、更有条理的方式来实现同样的事情,并且代码更易读?
【问题讨论】:
为什么你觉得这是不可维护的? 感觉像丑陋的代码。包含部分视图的视图,它会更新主视图上的 div。 如果你想使它可维护,你已经编写了很好的代码,然后在你编写的代码上使用适当的 cmets 以理解其他 你为什么用局部分割视图?只是出于 ajax 或任何其他原因? 唯一可以改进的就是这一行:ModelState.Remove("PresupuestoGlobal");这是一份综合指南(ModelState 未更改):pluralsight.com/guides/ 【参考方案1】:我会重构将 ajax 表单移到部分之外的视图。这样,在表单内呈现的完整部分在 ajax 帖子上刷新,不知道容器结构并解耦,每个视图都有自己的责任:
索引.cshtml
<div class="panel panel-default">
<div class="panel-heading">
@using (Ajax.BeginForm("CreateOrEditPresupuestoGeneralxx", new AjaxOptions() HttpMethod = "Post", UpdateTargetId = "form-content", InsertionMode = InsertionMode.Replace ))
<div id="form-content">
@Html.Partial("CreateOrEditPresupuestoGeneralxx", Model)
</div>
</div>
</div>
CreateOrEditPresupuestoGeneralxx.cshtml
@using xx.Relacionamiento.Modelo.Bussiness.Entities.Enumeraciones;
@using xx.Relacionamiento.Modelo.Bussiness.Entities;
@using Kendo.Mvc.UI;
@model PresupuestosGenerale
@Html.HiddenFor(h => h.PresupuestoGeneralId)
@Html.Hidden("Categoria",CategoriaEvento.xx.ToString())
<div class="row">
...
【讨论】:
这可能比原来的要好,但是它在部分中有一个提交按钮,但它提交的表单在部分之外。这对我来说似乎有点乱。 但这不是问题。这里partial的作用是让通过Ajax提交和redeaw表单内容。部分知道是表单内容,但不知道表单发布在哪里,是否是Ajax等,只知道它是表单内容,按钮是表单内容的一部分 提交按钮有一个onclick事件。表单是否需要了解的不仅仅是表单本身的内容,取决于该事件的作用。但是,是的,你几乎肯定是对的。 我没有注意到,但现在你指出了,这不是问题。首先,我不会在标记内绑定事件,而是在文档准备好时不显眼。通过这种方式,您可以决定是将事件代码作为部分的一部分,还是作为 form.submit 放在容器中。也许第二个会更干净,这取决于事件处理程序的作用【参考方案2】:这是我在一些项目中使用的示例之一。在这个例子中,不仅PartialView
被渲染,DropdownList
的值也被传递给PartialView
并显示在上面。
查看:
<div id="divPartialView">
@Html.Partial("~/Views/MyPartialView.cshtml", Model)
</div>
$(document).ready(function ()
$(".SelectedCustomer").change(function (event)
$.ajax(
url: '@Url.Action("GetPartialDiv", "Home")',
data: id: $(this).val() /*add other additional parameters */ ,
cache: false,
type: "POST",
dataType: "html",
success: function (data, textStatus, XMLHttpRequest)
SetData(data);
,
error: function (data) onError(data);
);
);
function SetData(data)
$("#divPartialView").html(data); //HTML DOM replace
);
控制器:
[HttpPost]
public PartialViewResult GetPartialDiv(int id /* ddl's selectedvalue */)
Models.GuestResponse guestResponse = new Models.GuestResponse();
guestResponse.Name = "this was generated from this ddl id:";
return PartialView("MyPartialView", guestResponse);
希望这会有所帮助...
【讨论】:
以上是关于如何正确使用带有 Ajax Begin 表单的局部视图的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 JQuery 和 formData 正确获取表单数据