我正在使用Doctrine并尝试在用户浏览器上显示的笔记集合上实现无限滚动。
该应用程序是非常动态的,因此当用户提交新笔记时,除了发送(和存储)到服务器之外,该笔记还会立即添加到集合的顶部。
这就是为什么我不能使用传统的分页方法,您只需将页码发送到服务器,服务器就会从中计算出偏移量和结果数量。
举个例子来说明我的意思,假设显示 20 个注释,然后用户再添加 2 个注释,因此显示 22 个注释。如果我只是请求"页面 2",则该页面的前 2 项将是当前向用户显示的页面的最后两项。
这就是为什么我追求一种更复杂的方法,这就是我将要解释的方法。
请考虑以下代码,它是服务器代码的一部分,用于处理 AJAX 请求以获取更多说明:
// $lastNoteDisplayedId is coming from the AJAX request
$lastNoteDisplayed = $repository->findBy($lastNoteDisplayedId);
$allNotes = $repository->findBy($filter, array('numberOfVotes' => 'desc'));
$offset = getLastNoteDisplayedOffset($allNotes, $lastNoteDisplayedId);
// retrieve the page to send back so that it can be appended to the listing
$notesPerPage = 30
$notes = $repository->findBy(
array(),
array('numberOfVotes' => 'desc'),
$notesPerPage,
$offset
);
$response = json_encode($notes);
return $response;
基本上我需要写方法getLastNoteDisplayedOffset
,给定整套笔记和一个特定的笔记,它可以给我它的偏移量,以便我可以用它来分页以前的教义陈述。
我知道可能的一种实现是:
getLastNoteDisplayedOffset($allNotes, $lastNoteDisplayedId) {
$i = 0;
foreach ($allNotes as $note) {
if ($note->getId() === $lastNoteDisplayedId->getId()) {
break;
}
$i++;
}
return $i;
}
我不想遍历所有音符,因为性能是一个重要因素。我想知道教义本身是否有一种方法,或者您是否可以提出不同的方法。
在一个旧项目中,我曾经按照自己的需要创建一个无限滚动。
我所做的是一个可以接收称为偏移量的参数的 Web 服务。
在我的 javascript 中,我添加了一个事件来检测用户是否向下滚动了足够的文档。当事件被触发时,我创建 ajax 查询,我计算页面中存在的元素数量(它们在一个表中)。
$(window).scroll(function(){
if ($(window).scrollTop() + $(window).height() >= $(document).height() - 50){
lastEvents();
}
});
var isLoading = false;
function lastEvents() {
if (!isLoading) {
isLoading = true;
var nb = $('table#events tr').length
$.ajax({
url: 'getEvents.php',
data: {
offset: nb
},
success: function (data) {
isLoading = false;
$('.table#events').append(data);
}
});
}
}
然后在我的教义查询中,我做了这样的事情:
$events = Doctrine_Query::create()
->select()
->from('Events e')
->orderBy('e.created_at ASC')
->limit(10)
->offset($_REQUEST['offset'])
->execute();
然后在我的模板中,我生成新的表行,该行将附加 JS。
注意:现在,我肯定会返回json,然后在客户端解析它;)
我没有
使用Doctrine,但解决方案将涉及不使用偏移量而是使用WHERE条件。 我猜应该是这样的,但我不知道教义的语法:
$notes = $repository->findBy(
array('id < ' => $lastNoteDisplayedId), // I'm guessing the first param is the where condition, don't know the syntax
array('createdAt' => 'desc'),
$notesPerPage
// remove the offset
);