How to correctly use Partial views with Ajax Begin

2019-03-25 10:14发布

I have the following code, in my 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 />

Then I have the following 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>

Then on my controller I have business logic that returns something different depending on conditions

 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);
                }

So, when the user submits the form, the container from the index view is replaced with the new html.

The code works perfectly fine, however I feel that the code is ugly, not maintainable and difficult to read.

My questions, is, with asp.net mvc and ajax is there a better and more organized way to achieve the same thing with more readable code?

2条回答
ら.Afraid
2楼-- · 2019-03-25 10:25

Here is one of the example that I used in some of my projects. In this example not only PartialView is rendered, also a DropdownList value is passed to the PartialView and displayed on it.

View :

<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
    } 
});


Controller :

[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);
}

Hope this helps...

查看更多
趁早两清
3楼-- · 2019-03-25 10:32

I would refactor the views moving the ajax form outside the partial. That way the full partial which is rendered inside the form is refreshed on ajax posts, keeps unaware and decoupled of container structure and every view has their own responsibility:

Index.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">
...
查看更多
登录 后发表回答