web-dev-qa-db-ja.com

Laravel 5でマージされたコレクションをページ分割するにはどうすればよいですか?

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);
}
18
KinsDotNet

ただし、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);
}
20
itachi

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;
}
30
Michael Holland

両方のセットにページ番号を付けて、それらをマージしてみてください。ページ区切りの詳細については、 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;
    }
}
6
Kelt

ページネーションコレクションの最良の方法:

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)
2
Rohallah Hatami

フォローしてみてください。

$arr = $pets->toArray();
$paginator->make($arr, count($arr), $perPage);