Rails每次点击都会创建多个购物车记录

时间:2015-10-08 08:36:30

标签: javascript ruby-on-rails ajax shopping-cart

我按照本指南创建购物车模型: https://richonrails.com/articles/building-a-shopping-cart-in-ruby-on-rails

我让它成功运作,但仍有问题。当我加载页面并添加项目时,添加一个项目,如果我转到另一个页面,然后再次加载主页,通过我有的侧栏菜单,我点击一个产品,并添加相同的产品3购物车的时间。我转到另一页并返回,每次点击5项,每次点击7项。 我不知道为什么会这样,我甚至不知道我的代码的哪一部分要显示,所以有人可以帮助我。 如果我重新加载页面(通过单击地址栏并输入),则会返回每次点击添加一个项目。

提前致谢

编辑:在第一条评论建议之后,这是控制器代码。

def create
    @invoice = current_invoice
    @invoice_product = @invoice.invoice_products.new(invoice_product_params)
    @invoice.save
    session[:invoice_id] = @invoice.id
end

def update
    @invoice = current_invoice 
    @invoice_product = @invoice.invoice_products.find(params[:id])
    @invoice_product.update.attributes(order_item_params)
    @invoice_products = @invoice.invoice_products
end

def destroy
    @invoice = current_invoice 
    @invoice_product = @invoice.invoice_products.find(params[:id])
    @invoice_product.destroy
    @invoice_products = @invoice.invoice_products
end

private
def invoice_product_params
    params.require(:invoice_product).permit(:id, :invoice_id, :product_id, :price, :tax, :value)
end

1 个答案:

答案 0 :(得分:2)

  

将相同的产品添加到购物车3次。我去   另一页并返回每次点击5项,再次每项7项   然后按

这有Turbolinks的所有标志和糟糕的JS绑定。

-

让我解释一下......

  

Turbolinks可以更快地在您的网络应用中添加以下链接。   而不是让浏览器重新编译JavaScript和CSS   在每个页面之间更改,它使当前页面实例保持活动和   仅替换头部的主体(或部分)和标题。认为   CGI与持久性过程。

简而言之,Turbolinks使用&#34; Ajax&#34;加载下一页的<body>,替换当前的<body>内容。虽然这确实加快了处理速度(通过消除重新编译CSS /图像的需要),但它会对JS绑定造成严重破坏。

JS&#34;绑定&#34;到DOM中的元素:

enter image description here

它希望绑定到元素。在大多数情况下,这非常有效:

element = document.getElementById("your_element").addEventListener('click', function() {
   console.log('anchor');
});

然而,使用Turbolinks(尤其是JQuery)的问题是绑定可能会多次发生,具体取决于Turbolinks将新数据加载到DOM中的次数。

问题是因为你的 Javascript不是刷新,但你的DOM元素是,JS正在将它们视为 new 元素,从而触发函数x每次点击的次数。有点像n+1我想。

-

在回答您的问题时,问题在于您的JS绑定:

#app/assets/javascripts/application.js
bind = function() {
    $("#shopping_cart").on("click", function(){
        //payload
    });
};
$(document).on("ready page:load", bind);

以上是#34; local&#34;选择元素并使用page:load Turbolinks hook,将确保每次请求Turbolinks时都会刷新。

如果您想在每次调用Turbolinks时不必重新声明,只需delegate from the document

#app/assets/javascripts/application.js
$(document).on("click", "#shopping_cart", function(){
   //payload
});