【问题标题】:rails link_to :remote from within ajax-loaded contentrails link_to :从 ajax 加载的内容中远程
【发布时间】:2011-05-02 05:06:28
【问题描述】:

大家好,我正在开发一个应用程序,但在使用新的 Rails 3 link_to 时遇到了困难。情况是这样的——我的“主页”页面上有两个 div,每个 div 都使用 ajax 在 document.load 中填充。这按预期工作。

在我加载到这些 div 中的页面内容中,我想使用 link_to... :remote => true 功能。源使用 data-remote="true" 标记按预期呈现,但是当我单击链接时,它们被完全忽略(链接被视为常规超链接)。

我编写的 .rjs 文件可以正确处理所有内容(因为它们在硬编码时可以工作),所以这不是问题。

这里是 ajax 加载内容的 html 源代码:

<div>
  <a href="/cart/add/2" data-remote="true">Link A</a>
  <a href="/cart/add/1" data-remote="true">Link B</a> 
</div>

在通常嵌入页面时单击其中一个链接会导致我的购物车正确更新...但是,当我使用 AJAX 将此内容动态加载到页面中时,链接会跟随并忽略 data-remote= “真”……

最初我认为这与原型在 AJAX 内容中未正确加载有关,但我已经检查了所有这些,它并没有改变任何事情......

我真的很困惑...有人对此有想法吗?

# add method of controller
def add
  product = Product.find_by_id(params[:product_id])
  params[:quantity] ||= 1
  params[:price] ||= product.price

  unless product.nil?
    @line = session[:cart].purchase_lines.select {|l| l.product_id == product.id}.first
    unless @line.nil?
      @line.quantity = (@line.quantity + params[:quantity].to_i)
    else # create a new purchase_line in the cart
      @line = session[:cart].purchase_lines.build({ :product_id => product.id, :price => params[:price], :quantity => params[:quantity].to_i })
    end
  else
    flash[:error] = "Unable to add the selected product"
  end
end  

还有我的 rjs

# add.rjs
page.if page['product_' << @line.product_id.to_s] do
  page.replace 'product_' << @line.product_id.to_s, :partial => 'line'
page.else
  page.insert_html :bottom, 'cart', :partial => 'line'
end

page.replace_html 'sub_total', number_to_currency(session[:cart].sub_total, :unit => '$')
page.replace_html 'tax', number_to_currency(session[:cart].tax, :unit => '$')
page.replace_html 'total', number_to_currency(session[:cart].sub_total+session[:cart].tax, :unit => '$')
page.visual_effect :highlight, 'product_' << @line.product_id.to_s, :duration => 1

【问题讨论】:

    标签: javascript ruby-on-rails ruby ajax


    【解决方案1】:

    我很确定这里的问题是,当您的页面第一次加载时,您正在使用的 Rails UJS javascript 库(默认为原型,或 jQuery 等)将侦听器绑定到 onclick 事件锚(链接)元素。但是,当您使用新标记动态更新页面时(在这种情况下通过 ajax),新的锚标记不会接收此绑定,因为 UJS 库仅在页面首次加载时才执行此操作。如果您使用 jQuery 作为 UJS,您应该查看位于 jQuery API docs

    中的 jQuery.live() 事件处理程序附件

    API 的描述如下:

    描述:将处理程序附加到 匹配的所有元素的事件 当前选择器,现在和在 未来。

    具体来说,您应该给将接收 AJAX 加载内容的 div 一个 id,比如说“购物车链接”,然后在页面中添加一些类似于以下内容的 javascript:

    $('#cart-links a').live('click', function() {
      // make your AJAX calls here
    });
    

    如果您使用的是原型,我不确定是否有等效的原型。

    我对 javascript 和 Rails 了解得越深,我就越意识到很多 Rails javascript 助手实际上使 javascript 开发和 AJAX 处理变得更加困难,我倾向于只使用原始 jQuery。

    祝你好运!

    【讨论】:

      【解决方案2】:

      我同意 Patrick 的观点,您可能会在加载 DOM 时进行绑定,因此任何新添加的元素都不会被绑定。如果您正在使用的 javascript(即 Prototype)没有 jQuery 的 live() 之类的功能,您可以将绑定逻辑封装在一个函数中,该函数取消绑定然后重新绑定自身(您可能想要命名事件,这样您就不会取消绑定任何其他处理程序,但我不确定 Prototype 是否支持命名空间事件),然后您可以在插入新元素时调用该函数。或者,您可以隔离与新创建元素的绑定,而不是绑定到具有该类名或标记名的每个元素。

      和 Patrick 一样,我也更喜欢使用原始 jQuery。这样,您就不必了解 rails.js 的功能,也不必针对它不符合您要求的情况采用变通方法。作为一个开发者,你应该知道你想让你的 javascript 做什么,然后去做。如果您更喜欢使用 Prototype,您仍然应该制作自己的 rails.js,但我认为 jQuery 确实要好得多。

      【讨论】:

      • 我同意... jQuery 好多了,但我想尝试 RJS/proto,因为我正在观看 railscasts,他们让它看起来很简单
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多