我目前有无休止的分页设置,如下所示:
events_controller.rb
class EventsController < ApplicationController
respond_to :html, :js
def index
@events = Event.page(params[:page]).per(5)
respond_with(@events)
end
end
events/index.html.erb
<div id="events-container">
<%= render :partial => 'events', :locals => {events: @events} %>
</div>
events/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>
assets/javascripts/events/events_endless_page.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();
}
});
events/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轮询来刷新事件页面时,就会出现这个问题。
assets/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中的代码,以使刷新行为正常工作:
events/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页?这些只是其中的几个挑战。希望有人能提供指导。我知道这是一个冗长的问题,所以感谢您的关注。
我不完全确定"无休止的分页"这个词,即使你不想立即显示所有内容,内容的数量不是有限制吗?
这可能对您有效:https://github.com/paulirish/infinite-scroll
我会使用它来滚动并获得更多的结果,这是经过尝试和测试的:
- 使用对现有、已在页面上的事件进行的更新(包括删除)来更新这些事件
- 添加新事件
我强烈建议你把你的民意调查人员分成两个不同的民意调查小组,每个小组负责一个行动。
第一个将获取页面上当前事件的所有事件ID,并检查它们的更新。已删除的事件将从页面中删除;更新后的事件将更新到位。
第二种方法是查找在"上次轮询"时间戳之后创建的事件,并将其插入页面顶部。
我不确定第二个轮询器会如何影响无休止页面中事件的分页,但我认为这个挑战是可以解决的。
我的建议是创建一个共享AJAX方法,该方法检查内容的使用年限,然后刷新特定的内容(比如文章、可订购项目等),这段代码由分页代码或自动定时轮询调用。
以场景为例
用户加载页面(1/4),其中包含4个部分。用户不滚动,你有4个项目需要在170000毫秒时更新。你更新的计时器会循环浏览这4个项目,并为这4个调用独立的AJAX更新程序。
用户加载页面(1/4),然后向下滚动到页面(2/4)。您的分页代码呈现出新的4个部分。用户将页面保持在适当的位置,因此在170000毫秒后,您需要刷新这4个页面。就像上面的#1一样,计时器调用循环遍历项目5-8(第2页的内容项目),并为这4个调用独立的更新程序。
用户加载页面(1/4),然后向下滚动到页面(4/4)。您的分页代码呈现出所有部分(16个部分中的16个部分)。用户将页面保持在适当的位置,因此在170000毫秒后,您需要刷新这4个页面。就像#1&2以上的定时器调用循环通过项目20-24,并调用为这4更新的独立。
用户加载页面(1/4),然后向下滚动到页面(2/4)并离开它。就像上面的#2一样,4个项目由计时器更新。然后用户滚动回页面(1/4),因此分页/滚动代码通过一个小(250ms)计时器调用(1-4)的独立功能,该计时器检查内容是否需要刷新并执行
用户加载页面(1/4),然后向下滚动到页面(4/4)并离开它。就像#4一样,内容刷新最后一页,然后向上滚动。当滚动事件发生时,它会通过一个针对现有项目的小型(250毫秒)计时器触发ajax更新程序,该计时器会检查是否需要刷新这些项目,以及是否需要更新。
注意事项
- 它允许您打破";这是否需要更新";逻辑转换为一个共享函数,该函数同时适应分页和用户保持页面静止的行为
- 它允许您确保只更新显示的内容,并且该逻辑不会在两组函数中重复,因此您的逻辑可以在以后以最小的影响进行更新
- 当被分页代码调用时具有该函数的小延迟;滚动";备份允许用户快速滚动经过某个元素,以至于不值得调用并使用服务器资源刷新屏幕上没有的内容