无尽的分页和ajax刷新

时间:2013-08-19 01:55:25

标签: ajax ruby-on-rails-3 pagination kaminari

我目前有无限的分页设置,如下所示:

events_controller.rb

class EventsController < ApplicationController

  respond_to :html, :js

  def index
    @events = Event.page(params[:page]).per(5)
    respond_with(@events)
  end

end

事件/ index.html.erb

<div id="events-container">
  <%= render :partial => 'events', :locals => {events: @events} %>
</div>

事件/ events.html.erb

<div id="events-table-container" data-events-url="<%= current_url %>">

  <table id="events-tbl">
    <tbody id="events-tbl-body">
      <%= render events %>
    </tbody>
  </table>

  <%= paginate events %>

</div>​

资产/ Javascript角/活动/ events_endless_paging.js

$(function() {
  var isScrolledIntoView;
  isScrolledIntoView = function(elem) {
    var docViewBottom, docViewTop, elemBottom, elemTop;
    docViewTop = $(window).scrollTop();
    docViewBottom = docViewTop + $(window).height();
    elemTop = $(elem).offset().top;
    elemBottom = elemTop + $(elem).height();

    return (elemTop >= docViewTop) && (elemTop <= docViewBottom);
  };

  if ($('#events-container .pagination').length) {
    $(window).scroll(function() {
      var url;
      url = $('#events-container .pagination .next a').attr('href');
      if (url && isScrolledIntoView('#events-container .pagination')) {
        $('#events-container .pagination').html("<span class='working-notice'>Fetching more...</span>")

        return $.getScript(url);
      }
    });

    return $(window).scroll();
  }
});

事件/ index.js.erb的

$('#events-tbl-body').append('<%= j render(@events) %>');

<% if (@events.current_page < @events.num_pages) %>
    $('.pagination').replaceWith('<%= j paginate(@events) %>');
<% else %>
    $('.pagination').remove();
<% end %>

这就像魅力和所有。当我尝试集成setTimeout ajax轮询来刷新事件页面时,会出现此问题。

资产/ Javascript角/活动/ event_poller.js

$(document).on('ready', function() {
  App.Pollers.Event.poll();
});

App.Pollers.Event = {

  frequency: 170000,

  poll: function() {
    setTimeout(App.Pollers.Event.request, App.Pollers.Event.frequency);
  },

  request: function() {
    eventsRequest = $.getScript($('#events-table-container').data('events-url'));
    return eventsRequest;
  },

};

删除上面的无限分页代码,这里是events / index.js.erb中的代码看起来只是刷新行为才能正常工作:

事件/ index.js.erb的

$('#events-container').html('<%= j(render :partial => 'events', :locals => {events: @events}, :formats => :html) %>');

App.Pollers.Event.poll();

我的挑战是让无休止的分页代码和ajax刷新代码协同工作。如果我使用带有无限分页代码的ajax刷新,那么最终发生的事情是重复事件被附加到 events-tbl-body 元素。另一个问题是,假设用户向下滚动页面,无限的分页将第2页结果附加到第1页结果,那么ajax刷新代码如何知道如何显示第1页和第2页?这些只是一些挑战。希望有人可以提供指导。我知道这是一个冗长的问题,所以感谢你的关注。

4 个答案:

答案 0 :(得分:0)

我对你这么大的问题感到困惑......

几个月前,我也在尝试与kaminari和this进行无尽的分页。 链接帮助了我。

答案 1 :(得分:0)

我不完全确定“无限寻呼”一词,即使您不想立即显示所有内容,内容数量也没有限制吗?

这可能适合您: https://github.com/paulirish/infinite-scroll

我会用它来滚动并获得更多结果,这是经过试验和测试的:

答案 2 :(得分:0)

我看到轮询器有两种不同的用途,如果我错了就纠正我:

  1. 更新现有的已有页面事件,并对这些事件进行更新(包括删除)。
  2. 添加新活动。
  3. 我强烈建议您将轮询器分成两个不同的轮询器,每个轮询器负责一个动作。

    第一个将获取当前页面上的那些事件的所有事件ID,并检查它们的更新。删除的事件将从页面中删除;更新的事件将在适当的位置更新。

    第二个将查找在“您最后一次轮询”时间戳之后创建的事件,并将其插入页面顶部。

    我不确定第二个轮询器会如何影响你的无限页面的事件分页,但我认为这个挑战是可以解决的。

答案 3 :(得分:0)

我的建议是创建一个共享的AJAX方法,检查内容的年龄,然后刷新特定的内容(例如文章,可订购的项目等),并通过分页调用这段代码代码或自动定时轮询。

作为示例的场景

  1. 用户加载页面(1/4),它包含4个部分。用户不滚动,您有4件需要在170000毫秒更新。您更新的计时器将遍历这4个项目并为那些4调用独立的AJAX更新程序。

  2. 用户加载页面(1/4),然后向下滚动到页面(2/4)。您的分页代码会呈现新的4个部分。用户将页面保持在原位,因此在170000毫秒之后你需要刷新那些4.就像定时器调用上面的#1循环通过5-8项(第2页的内容项)并为那些4调用独立的更新程序。

  3. 用户加载页面(1/4),然后向下滚动到页面(4/4)。您的分页代码会呈现所有部分(16个部分中的16个部分)。用户将页面保持在原位,因此在170000毫秒之后你需要刷新那些4.就像#1&amp;定时器调用上方的2循环通过项目20-24并调用独立更新为那些4。

  4. 用户加载页面(1/4)然后向下滚动到页面(2/4)并离开它。就像上面的#2一样,4个项目由计时器更新。用户然后向上滚动到页面(1/4),因此分页/滚动代码通过一个小的(250ms)计时器调用(1-4)的独立功能,该计时器检查内容是否需要刷新并且如此。

  5. 用户加载页面(1/4)然后向下滚动到页面(4/4)并离开它。就像#4一样,内容在最后一页刷新,然后向上滚动。当滚动事件发生时,它会通过一个小的(250ms)计时器触发ajax更新程序,用于已经存在的项目,检查是否需要刷新它们,如果是,则更新。

  6. 考虑

    • 它允许您将“需要更新”逻辑分解为共享函数,该函数适应分页和用户离开页面的行为。
    • 它允许您确保只更新显示的内容,并且他的逻辑不会在两组函数中重复,因此您的逻辑可以在以后更新,影响最小。
    • 当“滚动”备份时,由分页代码调用此函数的延迟很小,允许用户滚动元素的速度太快,以至于不值得进行调用并使用服务器资源刷新屏幕上没有的内容。