简体   繁体   English

rails link_to:远离ajax加载的内容

[英]rails link_to :remote from within ajax-loaded content

Hey everyone, I'm working on an application and I'm having difficulty with the new Rails 3 link_to. 嘿大家,我正在开发一个应用程序,我在使用新的Rails 3 link_to时遇到了困难。 Here's the situation - I have two divs on my "home" page, and each div is populated at document.load with ajax. 这是情况 - 我的“主页”页面上有两个div,每个div都在document.load中填充ajax。 This works as expected. 这按预期工作。

In the content of the pages I'm loading into these divs, I want to use the link_to... :remote => true functionality. 在我加载到这些div中的页面内容中,我想使用link_to ...:remote => true功能。 The source renders as expected with the data-remote="true" tag, but when I click on the links, they're completely ignored (the link is treated as a regular hyperlink). 源使用data-remote =“true”标记按预期呈现,但是当我单击链接时,它们将被完全忽略(链接被视为常规超链接)。

I've written .rjs files that handle everything properly (because they work when hard-coded), so that's not the issue. 我已经编写了正确处理所有内容的.rjs文件(因为它们在硬编码时有效),所以这不是问题。

Here's the html source for the ajax-loaded content: 这是加载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>

Clicking on one of those links when normally embedded into the page causes my shopping cart to update correctly... however, when I dynamically load this content into the page with AJAX, the link just follows and ignores the data-remote="true"... 通常嵌入到页面中时单击其中一个链接会导致我的购物车正确更新...但是,当我使用AJAX将此内容动态加载到页面时,链接就会跟随并忽略data-remote =“true” ...

Originally I thought it had something to do with prototype not loading correctly in the AJAX stuff, but I've checked all of that and it doesn't change a thing... 最初我认为它与原型没有在AJAX中正确加载有关,但我已经检查了所有这些并且它没有改变一件事......

I'm really confused... Does anybody have a thought on this? 我真的很困惑......有没有人想过这个?

# 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  

and my rjs 和我的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

I'm pretty sure the problem here is that when your page loads the first time, the Rails UJS javascript library you're using (Prototype by default, or jQuery, etc.) binds a listener to the onclick event of the anchor (link) element. 我很确定这里的问题是当你的页面第一次加载时,你正在使用的Rails UJS javascript库(默认为Prototype,或jQuery等)将监听器绑定到锚点的onclick事件(链接) )元素。 However, when you update your page with new markup dynamically (via ajax in this case) the new anchor tags do not receive this binding because the UJS library only does it's thing when the page first loads. 但是,当您使用新标记动态更新页面时(在本例中为ajax),新的锚标记不会收到此绑定,因为UJS库仅在页面首次加载时执行此操作。 If you're using jQuery as your UJS you should look into the jQuery.live() event handler attachment located in the jQuery API docs 如果您使用jQuery作为您的UJS,您应该查看位于jQuery API文档中的jQuery.live()事件处理程序附件

The description from the API is as follows: API的描述如下:

Description: Attach a handler to the event for all elements which match the current selector, now and in the future. 描述:为现在和将来与当前选择器匹配的所有元素附加事件的处理程序。

Specifically you should give the div that will receive the AJAX loaded content an id let's say "cart-links", then add some javascript to the page similar to the following: 具体来说,你应该给将接收AJAX加载内容的div一个id让我们说“cart-links”,然后在页面中添加一些javascript,类似于以下内容:

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

I'm not sure if there's a Prototype equivalent if that's what you're using. 如果你正在使用它,我不确定是否有Prototype等效。

The further I've gotten into javascript and Rails, the more I realize that a lot of the Rails javascript helpers actually make javascript development and AJAX handling more difficult, and I tend to just use raw jQuery. 我越进入javascript和Rails,我就越发现很多Rails javascript助手实际上使javascript开发和AJAX处理更加困难,而且我倾向于使用原始jQuery。

Good luck! 祝好运!

I agree with Patrick, you are probably binding when the DOM is loaded so any newly added elements don't get bound. 我同意Patrick,你可能在加载DOM时绑定,所以任何新添加的元素都不会被绑定。 If the javascript you're using (ie Prototype) doesn't have functionality like jQuery's live(), you can encapsulate the bind logic in a function which unbinds and then rebinds itself (you may want to namespace the event so you don't unbind any other handlers, but I'm not sure whether or not Prototype supports namespacing events), and then you can call that function when the new element is inserted. 如果你正在使用的javascript(即Prototype)没有像jQuery的live()这样的功能,你可以将绑定逻辑封装在一个取消绑定然后重新绑定自身的函数中(你可能想要命名事件所以你不要unbind任何其他处理程序,但我不确定Prototype是否支持命名空间事件),然后你可以在插入新元素时调用该函数。 Alternatively, you can isolate your binding to the newly created element instead of binding to every element with that class name or tag name. 或者,您可以将绑定与新创建的元素隔离,而不是绑定到具有该类名或标记名的每个元素。

And like Patrick, I also prefer to use raw jQuery. 和Patrick一样,我也更喜欢使用原始jQuery。 This way you don't have to learn what rails.js does and hack in workarounds for scenarios where it doesn't do what you want. 通过这种方式,您无需了解rails.js的作用,也无需了解其无法执行所需操作的方法。 As a developer, you should know what you want your javascript to do, and do it. 作为开发人员,您应该知道自己想要javascript做什么,并且做到这一点。 If you prefer to use Prototype, you should still make your own rails.js, but really jQuery is a lot nicer in my opinion. 如果你更喜欢使用Prototype,你仍然应该制作自己的rails.js,但在我看来,jQuery确实更好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM