简体   繁体   English

在asp.net mvc中提交Ajax.BeginForm后,jQuery代码无法正常工作

[英]jQuery code doesn’t work properly after submitting Ajax.BeginForm in asp.net mvc

I tried to minimize huge problem to a small one so I created the new sample web project; 我试图将一个小问题最小化,所以我创建了新的示例Web项目; mvc-empty in VS. VS中的mvc-empty I created one view named „Index” in Home controller. 我在Home控制器中创建了一个名为“Index”的视图。 Index view code: 索引视图代码:

@model WebApplication16.ViewModels.Home.IndexVM
@{
    ViewBag.Title = "Index";
}

@Html.Partial("~/Views/Home/_Orders.cshtml", Model.Orders)

@section scripts{
    <script src="~/Scripts/jquery.validate.js"></script>
    <script src="~/Scripts/jquery.validate.unobtrusive.js"></script>
    <script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
    <script>
        $("#Type").change(function () {



            $('#order-current > img').remove();
            var currentOrder = "#Type_" + $("#Type").find('option:selected').text();

            var $img = $(currentOrder).clone();
            $img.removeClass("hidden");
            $("#order-current").append($img);

            $("#ajax-form").submit();
        });
    </script>
}

Home controller code: 家庭控制器代码:

public class HomeController : Controller
    {
        [HttpGet]
        public ActionResult Index()
        {
            IndexVM dataVM = new IndexVM();
            GetControlsDataSource(dataVM.Orders);

            return View(dataVM);
        }

        private static void GetControlsDataSource(OrdersVM dataVM)
        {
            List<SelectListItem> typeControlDataSource = new List<SelectListItem>();
            foreach (var en in Enum.GetValues(typeof(TypeEnum)))
            {
                SelectListItem item = new SelectListItem();
                item.Text = en.ToString();
                item.Value = ((int)en).ToString();
                typeControlDataSource.Add(item);
            }
            dataVM.TypeControlDataSource = typeControlDataSource;
        }


        [HttpPost]
        public ActionResult Pay(IndexVM dataVM)
        {
            GetControlsDataSource(dataVM.Orders);
            if (ModelState.IsValid)
            {
                dataVM.Orders.Info = "Info bla bla bla";
                return PartialView("~/Views/Home/_Orders.cshtml", dataVM.Orders);
            }
            else
            {
                return View(dataVM);
            }

        }
    } 

There is also a partial view named “_Orders”, which is rendered on the Index view.The code of _Orders partial view: 还有一个名为“_Orders”的局部视图,它在Index视图上呈现._Orders局部视图的代码:

@model WebApplication16.ViewModels.Home.OrdersVM

@using (Ajax.BeginForm("Pay", "Home", new AjaxOptions
{
    InsertionMode = InsertionMode.Replace,
    UpdateTargetId = "result",
}, new { id = "ajax-form" }))
{
    <div id="result">
        <div id="order-current">

        </div>


        <div>
            @Html.TextBoxFor(x => x.Name, new { @class = "form-control", style = "margin-top:10px;", id = "Name" })
            @Html.ValidationMessageFor(x => x.Name)
        </div>

        <div>
            @Html.DropDownListFor(x => x.Type, Model.TypeControlDataSource, new { @class = "form-control", style = "margin-top:10px;", id = "Type", })
            @Html.ValidationMessageFor(x => x.Type)
        </div>
        <div>
            <p>@Model.Info</p>
        </div>
        <button type="submit" class="btn btn-primary" name="ok"> OK</button>
    </div>


}

<div id="orders-container">
    <img id="Type_I" src="~/App_Images/Type_I.png" class="img-responsive hidden" />
    <img id="Type_II" src="~/App_Images/Type_II.png" class="img-responsive hidden" />
    <img id="Type_III" src="~/App_Images/Type_III.png" class="img-responsive hidden"/>
</div>
Index model is described by class IndexVM:
public class IndexVM
    {
        public IndexVM()
        {
            this.Orders = new OrdersVM();
        }

        public OrdersVM Orders { get; set; }
    }

_Orders model is described by class OrdersVM: _Orders模型由类OrdersVM描述:

public class OrdersVM
    {

        [Required]
        public string Name { get; set; }

        public string Info { get; set; }

        [Required]
        public TypeEnum Type { get; set; }

        public List<SelectListItem> TypeControlDataSource { get; set; }
    }


public enum TypeEnum
{
    I,
    II,
    III
}

After change of value in DropDownListFor control with id=”Type”, the picture from hidden field should be injected by jquery code located in Index view into container with id=”order-current” and after that operation the ajax-form should be submitted. 在使用id =“Type”的DropDownListFor控件中更改值后,隐藏字段中的图片应该由位于索引视图中的jquery代码注入到具有id =“order-current”的容器中,并且在该操作之后应该提交ajax-form 。 It works properly but after calling 它工作正常,但在打电话后

return PartialView("~/Views/Home/_Orders.cshtml", dataVM.Orders);

from the HomeController, the field Info is updated properly but the injected picture from the “order-current” div container is gone. 从HomeController中,字段Info正确更新,但“order-current”div容器中注入的图片消失了。 I tried to see what's wrong in Google Chrome using F12 button and there are no errors but appeared an infinite loop in “browserLink” script. 我尝试使用F12按钮查看Google Chrome中的错误,并且没有错误,但在“browserLink”脚本中出现了无限循环。 I can't explain why. 我无法解释原因。 All I want is to see the injected picture in container with id=”order-current after submitting the ajax-form. 我想要的是在提交ajax-form之后在容器中看到注入的图片,其中id =“order-current”。 How to do this and what I did wrong? 怎么做以及我做错了什么?

Thanks to my friend I finally solved the problem. 感谢我的朋友,我终于解决了这个问题。 After updating the “result” container, all events added by jQuery to controls located in this container are unpinned. 更新“result”容器后,将取消固定jQuery添加到此容器中的控件的所有事件。 That's why it crashes. 这就是崩溃的原因。 The way to make it work correctly is to create a function and pin it to the event OnComplete of AjaxBeginForm. 使其正常工作的方法是创建一个函数并将其固定到AjaxBeginForm的事件OnComplete上。 After each update of the result container via ajax, this function is called. 每次通过ajax更新结果容器后,都会调用此函数。 I also made a small mistake in Home controller because I inserted a wrong view model class. 我在Home控制器中也犯了一个小错误,因为我插入了一个错误的视图模型类。 After all changes, it looks like this; 在所有变化之后,它看起来像这样; Home controller code: 家庭控制器代码:

public class HomeController : Controller
    {
        [HttpGet]
        public ActionResult Index()
        {
            IndexVM dataVM = new IndexVM();
            GetControlsDataSource(dataVM.Orders);

            return View(dataVM);
        }

        private static void GetControlsDataSource(OrdersVM dataVM)
        {
            List<SelectListItem> typeControlDataSource = new List<SelectListItem>();
            foreach (var en in Enum.GetValues(typeof(TypeEnum)))
            {
                SelectListItem item = new SelectListItem();
                item.Text = en.ToString();
                item.Value = ((int)en).ToString();
                typeControlDataSource.Add(item);
            }
            dataVM.TypeControlDataSource = typeControlDataSource;
        }


        [HttpPost]
        public ActionResult Pay(OrdersVM dataVM)
        {
            GetControlsDataSource(dataVM);
            if (ModelState.IsValid)
            {
                dataVM.Info = "Info bla bla bla";
                return PartialView("~/Views/Home/_Orders.cshtml", dataVM);
            }
            else
            {
                return View(dataVM);
            }

        }
    }

Index view: 索引视图:

@model WebApplication16.ViewModels.Home.IndexVM
@{
    ViewBag.Title = "Index";
}

@Html.Partial("~/Views/Home/_Orders.cshtml", Model.Orders)

<div id="orders-container">
    <img id="Type_I" src="~/App_Images/Type_I.png" class="img-responsive hidden" />
    <img id="Type_II" src="~/App_Images/Type_II.png" class="img-responsive hidden" />
    <img id="Type_III" src="~/App_Images/Type_III.png" class="img-responsive hidden" />
</div>

@section scripts{
    <script src="~/Scripts/jquery.validate.js"></script>
    <script src="~/Scripts/jquery.validate.unobtrusive.js"></script>
    <script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
    <script>

        function imageOnChangeEvent() {
            $("#ajax-form").submit();
        }

        function OnCompleteAjaxForm() {

            $('#order-current > img').remove();
            var currentOrder = "#Type_" + $("#Type").find('option:selected').text();

            var $img = $(currentOrder).clone();
            $img.removeClass("hidden");
            $("#order-current").append($img);
        }

    </script>

}

_Orders partial view code: _Orders部分查看代码:

@model WebApplication16.ViewModels.Home.OrdersVM

    <div id="result">
        @using (Ajax.BeginForm("Pay", "Home", new AjaxOptions
        {
            InsertionMode = InsertionMode.Replace,
            UpdateTargetId = "result",
            OnComplete = "OnCompleteAjaxForm()"
        }, new { id = "ajax-form" }))
        {

            <div id="order-current">

            </div>


            <div>
                @Html.TextBoxFor(x => x.Name, new { @class = "form-control", style = "margin-top:10px;", id = "Name" })
                @Html.ValidationMessageFor(x => x.Name)
            </div>

            <div>
                @Html.DropDownListFor(x => x.Type, Model.TypeControlDataSource, new { @class = "form-control", style = "margin-top:10px;", id = "Type", onchange = "imageOnChangeEvent()" })
                @Html.ValidationMessageFor(x => x.Type)
            </div>
            <div>
                <p>@Model.Info</p>
            </div>
            <button type="submit" class="btn btn-primary" id="button_ok" name="ok"> OK</button>


        }
    </div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM