Doctrine を使用しており、ユーザーのブラウザーに表示されるメモのコレクションに無限スクロールを実装しようとしています。
アプリケーションは非常に動的であるため、ユーザーが新しいメモを送信すると、メモはサーバーに送信 (および保存) されるだけでなく、すぐにコレクションの先頭に追加されます。
これが、ページ番号をサーバーに送信するだけで、サーバーがオフセットとそこから結果の数を 計算する従来のページネーション方法を使用できない理由です。
たとえば、20 件のメモが表示され、ユーザーがさらに 2 件のメモを追加すると、22 件のメモが表示されます。単純に「ページ 2」を要求すると、そのページの最初の 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
、メモのセット全体と 1 つの特定のメモが与えられた場合、そのオフセットを与えることができるメソッドを記述する必要があります。これにより、前の Doctrine ステートメントのページ付けに使用できます。
おそらく可能な実装は次のようになります。
getLastNoteDisplayedOffset($allNotes, $lastNoteDisplayedId) {
$i = 0;
foreach ($allNotes as $note) {
if ($note->getId() === $lastNoteDisplayedId->getId()) {
break;
}
$i++;
}
return $i;
}
パフォーマンスは重要な要素であるため、すべてのノートをループするのは避けたいと思います。Doctrine 自体がメソッドを持っているのか、それとも別のアプローチを提案できるのか疑問に思っていました。