Error in Ajax tabs when using endless scroll with

2019-09-02 17:05发布

问题:

TL;DR

My AJAX tabs are not working together with my implementation of endless scrolling (will_paginate).

Details

I have a page that has ajax tabs that loads different actions in my controller to render a partial with different content. So the "popular-view" has +two remote: true links at the top. They work fine. They render the corresponding partial appropriately using the respond_to js.

The problem is that I'm also paginating these partials with will_paginate (endless scrolling like ryan bates' screencast).

This means that I dont want to run the code in the js.erb because the AJAX controlling my tabs is placed there. This means that its just replacing (.html) my content instead of appending the new content the way infinite scroll script is trying to do (and does on my other pages).

But even though I know it causes me problems I don´t know how to solve the problem:

PROBLEM: popular.js.erb

$("#feed-content").html("<%= escape_javascript(render(:partial => 'feed_content')) %>");


$('#products').append('<%= escape_javascript(render(:partial => 'feed_content', :products      => @products, :remote => true)) %>');
<% if @products.next_page %>
$('.pagination').replaceWith('<%= escape_javascript( will_paginate(@products)) %>');
<% else %>
$('.pagination').remove();
<% end %>

Products_controller

def popular
   @products = Product.paginate(:page => params[:page], :per_page => 6)
 respond_to do |format|
  format.html 
  format.js 
 end
end

def sale
   @products = Product.paginate(:page => params[:page], :per_page => 6)
 respond_to do |format|
  format.html 
  format.js 
 end
end

VIEW/popular.html.erb

<header>
<p>Sort by <%= link_to "popular", products_popular_path, :remote => true, :class => "active"%> or <%= link_to "sale", products_sale_path, :remote => true%></p> 
</header>
<div class="bucket layout-single-column" id="feed-content">
<%= render "feed_content", :products => @products%>
</div>
<%= will_paginate @products %>

Partial: _feed_content.html.erb

 <div id="products">
<% @products.each do |product|%>
  #CODE 
<% end %>

products.js.coffee

jQuery ->
  if $('.pagination').length
      $(window).scroll ->
              url = $('.pagination .next_page').attr('href')
              if url &&  $(window).scrollTop() > $(document).height() - $(window).height() - 50
                      $('.pagination').text('Fetching more products...')
                      $.getScript(url)
$(window).scroll()

回答1:

I found a solution myself. I added ID's to my "remote true"-links like this. In this case "popular":

<p>Sort by <%= link_to "popular", products_popular_path(:feed => "popular"), :remote => true, :class => "active", :id => "popular"%>

Then in the corresponding popular.js.erb file I added an onclick event to the ajax that controls the tabs. This means that the ajax only runs when the link is clicked at not when the page is supposed to do the endless-scrolling part.

$("#popular").click(function() {
$("#feed-content").html("<%= escape_javascript(render(:partial => "#{@partial_name}")) %>");
});

$('#products').append('<%= escape_javascript(render(:partial => "#{@partial_name}")) %>');
<% if @products.next_page %>
$('.pagination').replaceWith('<%= escape_javascript( will_paginate(@products)) %>');
<% else %>
$('.pagination').remove();
<% end %> 

There may be a better and cleaner way, but this worked for me. I have asked another question here that is almost the same as this one. Just if someone needs more details.

UPDATE:

The above solution required two clicks on the link to render the partial. The code beneath should be used instead:

$('#popular').bind('ajax:complete', function() {
  $("#feed-content").html("<%= escape_javascript(render(:partial => "popular_content")) %>");
});