web-dev-qa-db-ja.com

Ajax Beginformで部分ビューを正しく使用する方法

私の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を使用して、より読みやすいコードで同じことを実現するためのより適切で組織化された方法はありますか?

11
Luis Valencia

Ajaxフォームをパーシャルの外に移動するビューをリファクタリングします。このようにして、フォーム内にレンダリングされる完全なパーシャルがajaxポストで更新され、コンテナ構造を認識せずに分離し、すべてのビューが独自の責任を持ちます。

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">
...
10
tede24

これは、いくつかのプロジェクトで使用した例の1つです。この例では、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);
}

お役に立てれば...

1
Murat Yıldız