BluePersonとRedPersonの2種類のオブジェクトを含むストリームを作成しています。ストリームを作成するには、両方のオブジェクトをすべてフェッチしてから、1つのコレクションにマージします。そうしたら、ページネーションを行う必要がありますが、ページネーションは雄弁なモデルとDBクエリ用であり、コレクションではありません。手動でページネーターを作成することについて多くのことを見てきましたが、特にAPIのドキュメントはまばらです(Paginatorクラスが受け入れる引数を見つけることすらできないようです)。
コレクションをマージした結果をページ分割するにはどうすればよいですか?
public function index()
{
$bluePerson = BluePerson::all();
$redPerson = RedPerson::all();
$people = $bluePerson->merge($redPerson)->sortByDesc('created_at');
return view('stream.index')->with('people', $people);
}
ただし、paginateは雄弁なモデルとDBクエリ用であり、コレクションではないようです。
あなたが正しいです。しかし、コレクション用のページネータ関数があります。 forPage
Collection forPage(int $page, int $perPage)
残りは簡単です。
public function foo()
{
$collection = collect([1,2,3,4,5,6,7,8,9,0]);
$items = $collection->forPage($_GET['page'], 5); //Filter the page var
dd($items);
}
LengthAwarePaginatorを使用する場合は、単にインスタンス化します。前の回答のコメントで述べたように、このパスを設定する必要があります。ページネームをインスタンス化する前に、「currentPage」を解決し、返されるアイテムを設定することも確認する必要があります。これはすべて、インスタンス化の前後に実行できます。したがって、関数は次のようになります。
function paginateCollection($collection, $perPage, $pageName = 'page', $fragment = null)
{
$currentPage = \Illuminate\Pagination\LengthAwarePaginator::resolveCurrentPage($pageName);
$currentPageItems = $collection->slice(($currentPage - 1) * $perPage, $perPage);
parse_str(request()->getQueryString(), $query);
unset($query[$pageName]);
$paginator = new \Illuminate\Pagination\LengthAwarePaginator(
$currentPageItems,
$collection->count(),
$perPage,
$currentPage,
[
'pageName' => $pageName,
'path' => \Illuminate\Pagination\LengthAwarePaginator::resolveCurrentPath(),
'query' => $query,
'fragment' => $fragment
]
);
return $paginator;
}
両方のセットにページ番号を付けて、それらをマージしてみてください。ページ区切りの詳細については、 docs および api を参照してください。独自のページネーターを手動で作成する例を次に示します...
$perPage = 20;
$blue = BluePerson::paginate($perPage / 2);
$red = RedPerson::paginate($perPage - count($blue));
$people = PaginationMerger::merge($blue, $red);
以下にPaginationMergerクラスを含めました。
use Illuminate\Pagination\LengthAwarePaginator;
class PaginationMerger
{
/**
* Merges two pagination instances
*
* @param Illuminate\Pagination\LengthAwarePaginator $collection1
* @param Illuminate\Pagination\LengthAwarePaginator $collection2
* @return Illuminate\Pagination\LengthAwarePaginator
*/
static public function merge(LengthAwarePaginator $collection1, LengthAwarePaginator $collection2)
{
$total = $collection1->total() + $collection2->total();
$perPage = $collection1->perPage() + $collection2->perPage();
$items = array_merge($collection1->items(), $collection2->items());
$paginator = new LengthAwarePaginator($items, $total, $perPage);
return $paginator;
}
}
ページネーションコレクションの最良の方法:
1-これを\ app\Providers\AppServiceProviderのブート機能に追加します
/*
* use Illuminate\Support\Collection;
* use Illuminate\Pagination\LengthAwarePaginator;
*
* Paginate a standard Laravel Collection.
*
* @param int $perPage
* @param int $total
* @param int $page
* @param string $pageName
* @return array
*/
Collection::macro('paginate', function($perPage, $total = null, $page = null, $pageName = 'page') {
$page = $page ?: LengthAwarePaginator::resolveCurrentPage($pageName);
return new LengthAwarePaginator(
$this->forPage($page, $perPage),
$total ?: $this->count(),
$perPage,
$page,
[
'path' => LengthAwarePaginator::resolveCurrentPath(),
'pageName' => $pageName,
]
);
});
2-今後、すべてのコレクションについて、コードのようにページ分割することができます
$people->paginate(5)
フォローしてみてください。
$arr = $pets->toArray();
$paginator->make($arr, count($arr), $perPage);