Реализация бесконечной прокрутки с помощью Rails 3 и Jquery - PullRequest
5 голосов
/ 30 ноября 2011

Я пытаюсь реализовать бесконечную прокрутку моего проекта. Я использую смесь Railscast # 114 Endless Page и this .

Все отлично работает, кроме странного поведения, когда я пытаюсь остановить отправку запросов, когда страница достигает своего конца

Пока у меня есть:

Контроллер:

def show
    @title = Photoset.find(params[:id]).name
    @photos = Photoset.find(params[:id]).photo.paginate(:page => params[:page], :per_page => 20)
    respond_to do |format|
      format.js
      format.html
    end
end

Show.html.erb:

<% content_for :body_class, '' %>
<%= render 'shared/header' %>
<div id="photos_container">
    <div id="photos_header">
    <h2><%= @title %></h2>
    </div>
    <%= render :partial => 'photo', :collection => @photos %>
</div>
<%= render :partial => 'endless_scroll' %>

Javascript (загружен частично):

<script type="text/javascript">
(function() {
  var page = 1,
  loading = false,
  finish = false;

  function nearBottomOfPage() {
    return $(window).scrollTop() > $(document).height() - $(window).height() - 200;
  }

  function finish() {
    finish = true;
  }

  $(window).scroll(function(){
    if (loading) {
      return;
    }

    if(nearBottomOfPage() && !finish) {
      loading=true;
      page++;
      $.ajax({
        url: '/photosets/<%= params[:id] %>?page=' + page,
        type: 'get',
        dataType: 'script',
        success: function() {
          loading=false;
        }
      });
    }
  });
}());
</script>

show.js.erb

$("#photos_container").append("<%= escape_javascript(render :partial => 'photo', :collection => @photos) %>");
<% if @photos.total_pages == params[:page].to_i() %>
    page.call 'finish'
<% end %>

Как видите, на моем show.js.erb у меня есть page.call, который присваивает true переменной finish. Это останавливает запросы.

Дело в том, что он никогда не загружает последнюю страницу. Когда @photos.total_pages == params[:page].to_i() вместо простого вызова функции finish и установки переменной на true, это также препятствует запуску $("#photos_container").append("<%= escape_javascript(render :partial => 'photo', :collection => @photos) %>");.

Отправляет запрос в контроллер, запускает SQL, но не добавляет последнюю страницу.

Если я изменю условие на @photos.total_pages < params[:page].to_i(), оно будет работать, но отправит дополнительный запрос на несуществующую страницу.

Буду признателен за любую помощь в моей реализации. Я не уверен, есть ли более адекватный (Rails) способ сделать это.

1 Ответ

2 голосов
/ 07 августа 2012

Прежде всего вы можете визуализировать html из частичного, когда запрос имеет тип xhr:

def show
  photoset = Photoset.includes(:photos).find(params[:id])
  @title = photoset.name
  @photos = photoset.photo.paginate(:page => params[:page], :per_page => 20)
  if request.xhr?
    render '_photo', :layout => false
  end
end

Затем используйте вызов ajax:

$.ajax({
  url: '/photosets/<%= params[:id] %>?page=' + page,
  type: 'get',
  dataType: 'script',
  success: function(response) {
    $("#photos_container").append(response);
    if (response == "") {
      //stop calling endless scroll
    }
  });  
});
...