0

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

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>​

资产/javascripts/events/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 轮询以刷新事件页面时,就会出现此问题。

资产/javascripts/events/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

3 回答 3

0

我不完全确定“无休止的分页”一词,即使您不想立即显示所有内容,内容的数量是否也有限制?

这可能对你有用: https ://github.com/paulirish/infinite-scroll

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

于 2013-08-21T02:09:35.417 回答
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 和 2 计时器调用循环通过项目 20-24 并为这 4 个调用独立更新。

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

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

注意事项

  • 它允许您将“这是否需要更新”逻辑分解为一个共享函数,该函数同时适应分页和用户离开页面的行为。
  • 它允许您确保您只更新显示的内容,并且其逻辑不会在 2 组函数中重复,因此您的逻辑可以在以后更新而影响最小。
  • 当“滚动”备份时由分页代码调用时,此函数有一个小的延迟允许用户滚动过一个元素的速度如此之快以至于不值得进行调用并使用服务器资源来刷新内容的事件不在屏幕上。
于 2013-08-27T20:32:00.200 回答
0

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

  1. 使用对这些事件(包括删除)所做的更新来更新现有的、已经在页面上的事件。
  2. 添加新事件。

我强烈建议您将轮询器分成两个不同的轮询器,每个轮询器负责一个操作。

第一个将获取页面上当前事件的所有事件 ID,并检查它们的更新。已删除的事件将从页面中删除;更新的事件将就地更新。

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

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

于 2013-08-22T20:06:02.427 回答