【问题标题】:Rails is creating multiple shopping cart records per clickRails 每次点击都会创建多个购物车记录
【发布时间】:2016-01-05 18:31:37
【问题描述】:

我正在按照本指南创建购物车模型: 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

【问题讨论】:

  • 控制器代码将是一个好的开始!
  • 我发现在 application.html.erb 中将 true %> 从正文移动到头部有效,但这使我的侧边栏菜单停止工作。出于某种原因,如果 js 事件在主体上,它会在每个请求上重新附加。有什么帮助吗?
  • 恢复该行并删除 Turbolinks 并尝试一下:blog.steveklabnik.com/posts/…
  • 无论如何我都不喜欢 Turbolinks,但如果您确实想再次使用它,至少我们可以缩小问题范围。
  • 将其移回正文并删除 turbolinks,该行现在看起来像这样: 但是,问题仍然存在

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


【解决方案1】:

同一产品会被添加到购物车 3 次。我去 另一个页面并返回,每次点击 5 项,再次每次点击 7 项 点击

这具有 Turbolinks 和不良 JS 绑定的所有特征。

--

让我解释一下……

Turbolinks 使您的 Web 应用程序中的以下链接更快。 而不是让浏览器重新编译 JavaScript 和 CSS 在每次页面更改之间,它使当前页面实例保持活动状态和 仅替换正文(或部分)和标题中的标题。思考 CGI 与持久化进程。

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

JS“绑定”到 DOM 中的元素:

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

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

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

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

--

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

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

上面将为您选择元素的“本地”选择,并使用page:load Turbolinks hook 确保每次请求 Turbolinks 时都会刷新。

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

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

【讨论】:

  • 根据 RichardAE 的评论,删除 turbolinks 有效,使您的解释完全正确。但是,我不知道如何在我的 rails 应用程序上实现您的解决方案,因为 javascript 绑定是由 rails 完成的。它是一个带有 remote:true 的 form_for,它在提交时调用 create.js.erb。我从未明确告诉它将 create.js.erb 中的代码绑定到该表单中的提交按钮。
猜你喜欢
  • 2016-01-29
  • 2014-02-27
  • 2020-10-19
  • 1970-01-01
  • 1970-01-01
  • 2015-02-10
  • 1970-01-01
  • 2019-09-17
  • 1970-01-01
相关资源
最近更新 更多