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

时间:2016-09-22 16:48:35

标签: javascript c# jquery ajax asp.net-mvc

我试图将一个小问题最小化,所以我创建了新的示例Web项目; VS中的mvc-empty我在Home控制器中创建了一个名为“Index”的视图。索引视图代码:

@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>
}

家庭控制器代码:

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

        }
    } 

还有一个名为“_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模型由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
}

在使用id =“Type”的DropDownListFor控件中更改值后,隐藏字段中的图片应该由位于索引视图中的jquery代码注入到具有id =“order-current”的容器中,并且在该操作之后将ajax-form注入应该提交。它工作正常,但在调用后

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

,字段Info正确更新,但“order-current”div容器中注入的图片消失了。我尝试使用F12按钮查看Google Chrome中的错误,并且没有错误,但在“browserLink”脚本中出现了无限循环。我无法解释原因。 我想要的是在提交ajax-form之后在容器中看到注入的图片,其中id =“order-current”。怎么做以及我做错了什么?

1 个答案:

答案 0 :(得分:0)

感谢我的朋友,我终于解决了这个问题。更新“result”容器后,将取消固定jQuery添加到此容器中的控件的所有事件。这就是崩溃的原因。 使其正常工作的方法是创建一个函数并将其固定到AjaxBeginForm的事件OnComplete上。每次通过ajax更新结果容器后,都会调用此函数。我在Home控制器中也犯了一个小错误,因为我插入了一个错误的视图模型类。在所有变化之后,它看起来像这样; 家庭控制器代码:

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

        }
    }

索引视图:

@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>

}

_订单部分查看代码:

@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>