【问题标题】:jQuery AJAX event only firing oncejQuery AJAX 事件只触发一次
【发布时间】:2015-08-04 06:30:20
【问题描述】:

首先让我感谢@Jasen,他花了 9 天时间帮助我解决一个问题,他花时间帮助我对我来说意义重大。他正在帮助我解决这个问题,但在最后一秒,他们决定使用 AJAX,因为联系页面使用它,而从购物车中删除商品也使用它。

让我谈谈我的问题,我有视图(这是 MVC 5)循环加载所选类别的所有产品。我想使用 jQuery nd AJAX 将商品添加到购物车。这对于第一次添加到购物车时列表中的第一项非常有效。

我想我的问题是所有按钮的 id 都是 AddToCart 和 jQuery,我编写它的方式无法决定单击哪个按钮。

这是视图的代码

@model IEnumerable<AccessorizeForLess.ViewModels.DisplayProductsViewModel>

@{
    ViewBag.Title = "Products > Necklaces";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<link href="~/Content/Site.css" rel="stylesheet" />
<link href="~/Content/jquery.fancybox.css?v=2.1.5" rel="stylesheet" />
<link href="~/Content/jquery.fancybox-buttons.css?v=1.0.5" rel="stylesheet" />
<link href="~/Content/jquery.fancybox-thumbs.css?v=1.0.7" rel="stylesheet" />
<h2>Products > Necklaces</h2>
<div id="update-message"></div>
<p class="button">
    @Html.ActionLink("Create New", "Create")
</p>
@*@using (Html.BeginForm("AddToCart", "Orders", FormMethod.Post))*@
{
    <div id="container">
        <div id="sending" style="display:none;"><img src="~/Content/ajax-loader.gif" /></div>
        <div style="color:red" id="ItemAdded"></div>
        <div class="scroll">

            @foreach (var item in Model)
            {
                <div class="scroll2">
                    <div class="itemcontainer">
                        <table>
                            <tr>
                                <td id="@item.Id" class="divId">
                                    <div class="DetailsLink" id="@item.Id"> &nbsp;&nbsp;&nbsp;@Html.ActionLink(@item.Name, "Details", new { id = item.Id })</div>
                                    <br />
                                    <div id="@item.Id"></div>
                                    <div class="divPrice" id="@item.Price">@Html.DisplayFor(modelItem => item.Price)</div>
                                    <div class="divImg"><a class="fancybox-thumbs" href="@item.Image.ImagePath" title="@item.Image.AltText" data-fancybox-group="thumb"><img src="@item.Image.ImagePath" alt="@item.Image.AltText" title="@item.Image.AltText" /></a></div>
                                    <div>&nbsp;</div>
                                    <div class="divQuantity">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Quantity: @Html.TextBoxFor(modelItem => item.Quantity, new { @id = "quantity", @style = "width:50px;", @class = "formTextBox" })</div>
                                    <div class="form-group">
                                        <div class="col-md-offset-2 col-md-10">
                                            <input type="button" value="AddToCart" class="btn btn-default" id="AddToCart" />
                                        </div>
                                    </div>
                                    <div style="height:15px;"></div>
                                </td>
                            </tr>
                        </table>
                    </div>
                </div>
                    }
                    <div class="button">@Html.ActionLink("Back To Categories","Categories")</div>
                    <br />
       </div>        
    </div>
@*}*@

这是我的 jQuery 代码:

@section scripts {
    <script src="~/Scripts/jQuery-jScroll.js"></script>
    <script src="~/Scripts/jquery.fancybox.js?v=2.1.5"></script>
    <script src="~/Scripts/jquery.fancybox-thumbs.js?v=1.0.7"></script>
    <script src="~/Scripts/jquery.fancybox-buttons.js?v=1.0.5"></script>
    <script type="text/javascript">
            //$(function () {
            //    $('.scroll').jscroll({
            //        autoTrigger: true
            //    });
                $('.fancybox-thumbs').fancybox({
                    prevEffect: 'none',
                    nextEffect: 'none',

                    closeBtn: true,
                    arrows: false,
                    nextClick: false
                });

                // Document.ready -> link up remove event handler
                $("#AddToCart").click(function () {
                    //first disable the button to prevent double clicks
                    $("#AddToCart").attr("disbled", true);
                    $("#AddToCart").prop("value", "Adding...");
                    $("#ItemAdded").text("");
                    //now show the loading gif
                    $("#sending").css("display", "block");
                    // Get our values
                    var price = parseFloat($(".divPrice").attr("id"));
                    var quantity = parseInt($("#quantity").val());
                    var id = parseInt($(".divId").attr("id"));

                    $.ajax({
                        url: "@Url.Action("AddToCartAJAX", "Orders")",
                        type: "POST",
                        data: { "id": id, "quantity": quantity, "price": price },

                        //if successful
                        success: function (data) {
                            successfulCall()
                        },
                        error: function (data) {
                            alert(data.Message);
                        }
                    });

                    function successfulCall() {
                        //enable the send button
                        $("#AddToCart").attr("disbled", false);

                        //hide the sending gif
                        $("#sending").css("display", "none");

                        //change the text on the button back to Send
                        $("#AddToCart").prop("value", "Add to Cart");

                        //display the successful message
                        $("#ItemAdded").text("Your item has been added to your order.");

                        //clear out all the values
                        $("input#quantity").val("0");
                    }

                    function errorCall() {
                        $("#AddToCart").attr("disbled", false);
                        $("#sending").css("display", "none");
                        $("#AddtoCart").prop("value", "Add to Cart");
                        $("#ItemAdded").text(data.message);
                    }
                    //alert('Clicked!');
                });
            //s});
    </script>
}

有人可以告诉我我在这里做错了什么,以便我可以正常工作吗?

编辑#1

这里是更新的 jQuery 代码:

$(".AddToCart").click(function () {
//first disable the button to prevent double clicks
$(this).prop("disbled", true).prop("value", "Adding...");
$("#sending").css("display", "block");
var td = $(this).closest('td')

//traverse DOM and find relevant element 
var price = parseFloat(td.find(".divPrice").prop("id")),
    quantity = parseInt(td.find("#quantity").val()),
    id = parseInt(td.find(".divId").prop("id"));

$.ajax({
    url: "@Url.Action("AddToCartAJAX", "Orders")",
    type: "POST",
    data: { "id": id, "quantity": quantity, "price": price },
    //if successful
    success: function (data) {
        successfulCall()
    },
    error: function (data) {
        errorCall(data);
    }
});

它在进行客户端更改之前有效(仅授予一次并且仅针对列表中的第一项),因为我没有更改服务器端代码可能出了什么问题? 编辑#2

这就是它的全部内容

@model IEnumerable<AccessorizeForLess.ViewModels.DisplayProductsViewModel>

@{
    ViewBag.Title = "Products > Necklaces";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<link href="~/Content/Site.css" rel="stylesheet" />
<link href="~/Content/jquery.fancybox.css?v=2.1.5" rel="stylesheet" />
<link href="~/Content/jquery.fancybox-buttons.css?v=1.0.5" rel="stylesheet" />
<link href="~/Content/jquery.fancybox-thumbs.css?v=1.0.7" rel="stylesheet" />
<h2>Products > Necklaces</h2>
<div id="update-message"></div>
<p class="button">
    @Html.ActionLink("Create New", "Create")
</p>
@*@using (Html.BeginForm("AddToCart", "Orders", FormMethod.Post))*@
{
    <div id="container">
        <div id="sending" style="display:none;"><img src="~/Content/ajax-loader.gif" /></div>
        <div style="color:red" id="ItemAdded"></div>
        <div class="scroll">

            @foreach (var item in Model)
            {
                <div class="scroll2">
                    <div class="itemcontainer">
                        <table>
                            <tr>
                                <td id="@item.Id" class="divId">
                                    <div class="DetailsLink" id="@item.Id"> &nbsp;&nbsp;&nbsp;@Html.ActionLink(@item.Name, "Details", new { id = item.Id })</div>
                                    <br />
                                    <div id="@item.Id"></div>
                                    <div class="divPrice" id="@item.Price">@Html.DisplayFor(modelItem => item.Price)</div>
                                    <div class="divImg"><a class="fancybox-thumbs" href="@item.Image.ImagePath" title="@item.Image.AltText" data-fancybox-group="thumb"><img src="@item.Image.ImagePath" alt="@item.Image.AltText" title="@item.Image.AltText" /></a></div>
                                    <div>&nbsp;</div>
                                    <div class="divQuantity">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Quantity: @Html.TextBoxFor(modelItem => item.Quantity, new { @style = "width:50px;", @class = "formTextBox quantity" })</div>
                                    <div class="form-group">
                                        <div class="col-md-offset-2 col-md-10">
                                            <input type="button" value="AddToCart" class="btn btn-default AddToCart" />
                                        </div>
                                    </div>
                                    <div style="height:15px;"></div>
                                </td>
                            </tr>
                        </table>
                    </div>
                </div>
                    }
                    <div class="button">@Html.ActionLink("Back To Categories","Categories")</div>
                    <br />
       </div>        
    </div>
@*}*@
@section scripts {
    <script src="~/Scripts/jQuery-jScroll.js"></script>
    <script src="~/Scripts/jquery.fancybox.js?v=2.1.5"></script>
    <script src="~/Scripts/jquery.fancybox-thumbs.js?v=1.0.7"></script>
    <script src="~/Scripts/jquery.fancybox-buttons.js?v=1.0.5"></script>
    <script type="text/javascript">
            //$(function () {
            //    $('.scroll').jscroll({
            //        autoTrigger: true
            //    });
                $('.fancybox-thumbs').fancybox({
                    prevEffect: 'none',
                    nextEffect: 'none',

                    closeBtn: true,
                    arrows: false,
                    nextClick: false
                });

                // Document.ready -> link up remove event handler
                $(".AddToCart").click(function () {
                    //first disable the button to prevent double clicks
                    $(this).prop("disbled", true).prop("value", "Adding...");
                    $("#sending").css("display", "block");
                    var td = $(this).closest('td')

                    //traverse DOM and find relevant element 
                    var price = parseFloat(td.find(".divPrice").prop("id")),
                        quantity = parseInt(td.find(".quantity").val()),
                        id = parseInt(td.find(".divId").prop("id"));

                    $.ajax({
                        url: "@Url.Action("AddToCartAJAX", "Orders")",
                        type: "POST",
                        data: { "id": id, "quantity": quantity, "price": price },
                        //if successful
                        success: function (data) {
                            successfulCall()
                        },
                        error: function (data) {
                            errorCall(data);
                        }
                    });

                    function successfulCall() {
                        //enable the send button
                        $(this).prop("disbled", false).prop("value", "Add To Cart");

                        //hide the sending gif
                        $("#sending").css("display", "none");

                        //display the successful message
                        $("#ItemAdded").text("Your item has been added to your order.");

                        //clear out all the values
                        $("input#quantity").val("0");
                    }

                    function errorCall(data) {
                        $(this).prop("disbled", false).prop("value", "Add To Cart");
                        $("#sending").css("display", "none");
                        $("#ItemAdded").text(data.message);
                    }
                    //alert('Clicked!');
                });
            //s});
    </script>
}

编辑#2

这是 OrdersController 中 AddToCartAJAX 的代码:

public ActionResult AddToCartAJAX(int id, int quantity, decimal price)
{
    var cart = ShoppingCart.GetCart(this.HttpContext);

    cart.AddToCart(id, quantity, price);

    return RedirectToAction("Index");
}

以及 ShoppingCrt.cs 中的 AddToCart

public void AddToCart(int id, int quantity, decimal price)
{
    // Get the matching cart and product instances
    var order = entities.Orders.FirstOrDefault(
        c => c.OrderGUID == ShoppingCartId
        && c.OrderItems.Where(p => p.ProductId == id).FirstOrDefault().ProductId == id);

    if (order == null)
    {
        // Create a new order since one doesn't already exist
        order = new Order
        {
            InvoiceNumber = Guid.NewGuid().ToString(),
            OrderDate = DateTime.Now,
            OrderGUID = ShoppingCartId,
            IsShipped = false
        };
        entities.Orders.Add(order);

        // Save changes
        entities.SaveChanges();

        //add the OrderItem for the new order
        OrderItem oi = new OrderItem()
        {
            OrderId = order.OrderId,
            OrderGUID = ShoppingCartId,
            ProductId = id,
            ProductQuantity = quantity,
            ProductPrice = price
        };

        entities.OrderItems.Add(oi);
        entities.SaveChanges();
    }
    else
    {
        // If the item does exist in the cart, 
        // then add one to the quantity
        order.OrderItems.Where(p => p.ProductId == id).FirstOrDefault().ProductQuantity += quantity;
    }
}

希望有帮助

【问题讨论】:

  • 他是帮助我解决另一个问题的人。
  • 是的,我将 AddToCart 添加到您建议的按钮类中。
  • quantity 类到@Html.TextBoxFor(modelItem =&gt; item.Quantity?还有td.find(".quantity").val(),并为正确的选择器更改成功和错误方法
  • @Satpal 检查编辑#2
  • $(this) in successfulCallerrorCall 不引用 .AddToCart 使用 $(".AddToCart") 代替

标签: jquery ajax asp.net-mvc-5


【解决方案1】:

当您在循环中创建元素时,会创建重复的标识符。这会使您的 HTML 无效。

HTML 中的标识符必须是唯一的。 这是预期的行为。

您可以分配一个通用类,然后可以使用类选择器。在此示例中,我向按钮添加了AddToCart CSS 类。

HTML

@Html.TextBoxFor(modelItem => item.Quantity, new {@style = "width:50px;", @class = "formTextBox quantity" })

<input type="button" value="AddToCart" class="btn btn-default AddToCart" />

脚本

$(".AddToCart").click(function() {
    $(this).prop("disabled", true)
           .prop("value", "Adding...");

    var td = $(this).closest('td.divId')

    //traverse DOM and find relevant element 
    var price = parseFloat(td.find(".divPrice").prop("id")),
        quantity = parseInt(td.find(".quantity").val()),
        id = parseInt(td.find(".divId").prop("id"));

    //Your ajax call
});

我还建议您使用 data-* 前缀的自定义属性来存储任意数据。

 <div class="divPrice" data-price="@item.Price"></div>

可以使用.data() 获取,它还将值转换为适当的类型。

 var price = $('.divPrice').data("price");

注意:相应地更改其余选择器。

【讨论】:

  • 我在现有代码中实现了您的更改,但现在当它遇到我的 ajax 调用时,我得到一个 500(内部服务器错误),我检查了我的权限并且它们似乎是正确的。跨度>
  • @PsychoCoder,它与权限无关,根据建议,您必须进行大量更改才能达到结果,500 表示服务器端出现问题。
  • 你能检查我的编辑吗?我知道我想念的东西一定很简单。
  • @PsychoCoder,正如 Satpal 所指出的,500 错误是 serer 异常的结果。您需要显示您的控制器代码。
  • @PsychoCoder,return RedirectToAction("Index") 不能与 $.ajax() 一起使用,这将对您有所帮助 => stackoverflow.com/a/17745088
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-14
  • 1970-01-01
  • 1970-01-01
  • 2015-03-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多