LoginSignup
50
48

More than 1 year has passed since last update.

【Laravel】LengthAwarePaginatorを使ってページャーを実装 -Laravel5.5

Last updated at Posted at 2018-11-24

2021/9/6 修正
forpage()はコレクションのメソッドであるとのコメントを頂き、修正&追記しました。
@convers39 さんありがとうございます!
[修正]
配列→コレクション
[追記]
配列を表示したい場合はcollect()を使うことでコレクションへの変換が可能。

こんにちは!
現在、開発でLaravelを使っており、ページャーを実装する必要がありました。
他の記事を参考にしながら無事に実装することができたので、今回は「LengthAwarePaginatorを使ってページャーを実装するまでの流れ」について書きます。

■結果:1ページ当たり20表示

clientsというコレクションから1ページ当たり20ずつ表示するために記述したコードが下記。

$clients = new LengthAwarePaginator(
            $clients->forPage($request->page, 20),
            count($clients),
            20,
            $request->page,
            array('path' => $request->url())
        );

ここでそれぞれの項目は下記の内容を示しています。

[表示するコレクション] = new LengthAwarePaginator(
            [表示するコレクション]->forPage([現在のページ番号],[1ページ当たりの表示数]),
            [コレクションの大きさ],
            [1ページ当たりの表示数],
            [現在のページ番号],
            [オプション(ここでは"ページの遷移先パス")]
        );

表示したいものが配列の場合はcollect()を使い、コレクションに変換することで動作します。

$clients = collect($clients) // 配列→コレクション

■実装に至るまでの流れ

〇コレクションが分割できるまで

上記のコードができるまでに試したことを書いていきます。

はじめ、書いていたコードが下記になります。
ここでは、1ページ当たりの表示数は5に設定してあります。

$clients = new LengthAwarePaginator(
            $clients,
            count($clients),
            5,
            1,
            array('path' => $request->url())
        );

これをdd()メソッドで見てみると下記のようになっていました。
分割されないfruits配列.png

分割されていません。
コードが機能していれば、この時点で$clientsコレクションが5つずつ分割されるため、
[#items: array:5]と表示されるはずだと考えていました。

ここで、laravelの公式ドキュメントを参照したところ。

Note: 自前でペジネーターインスタンスを生成する場合、ペジネーターに渡す結果の配列を自分で"slice"する必要があります。その方法を思いつかなければ、array_slice PHP関数を調べてください。
引用:Laravel 5.5 データベース:ペジネーション
https://readouble.com/laravel/5.5/ja/pagination.html

配列を指定した表示数に分割する必要があるようです。
続いて下記の記事を見つけました。

Laravel 5.4 LengthAwarePaginator
https://stackoverflow.com/questions/43601095/laravel-5-4-lengthawarepaginator

どうやら同じ状況で、指定した値に分割できていないようです。質問に対する回答を見ると、forpage()メソッドを使用していました。

forPage()
forPageメソッドは指定されたページ番号を表すアイテムで構成された新しいコレクションを返します。このメソッドは最初の引数にページ番号、2つ目の引数としてページあたりのアイテム数を受け取ります。
引用:Laravel 5.5 データベース:コレクション
https://readouble.com/laravel/5.5/ja/collections.html

上記の2つを参考にしながら書いたコードが下記になります。
これを再びdd()を使って見てみると。

$clients = new LengthAwarePaginator(
            $clients->forPage(1,5),
            count($clients),
            5,
            1,
            array('path' => $request->url())
        );

分割されたclients配列.png

分割されました!

〇表示内容が同じ&ページ番号が変わらない

分割されたので実際の画面を表示して動作を確認したところ、
下記の機能ができていませんでした。

・1ページ目と同じ内容が表示される

→forPage()メソッドで画面に表示するコレクションが変わっていないからでは?
解決策:1つめの引数を設定する

まず、forPage()メソッドの1つ目の引数を「1→2」に変えてみました。

$clients = new LengthAwarePaginator(
            $clients->forPage(2,5),
            count($clients),
            5,
            1,
            array('path' => $request->url())
        );

        dd($clients);

結果
forPage()の引数を変えてみる.png

分割された2番目のコレクションが表示されました。

・ページネーションの番号が変わらない

→現在のページ数である、CurrentPageが変わっていない
解決策:LengthAwarePaginatorの4つ目の引数をリクエストから受け取るようにする

ページネーションの次のページをクリックしたときのURLが
下記のようになっていたので、この値を現在のページ番号に設定すればよいのではと考えました。

URL: /list?page=2

forPage()の1つ目の引数とLengthAwarePaginatorの4つ目の引数を
「$request->page」に設定しました。


$clients = new LengthAwarePaginator(
            $clients->forPage($request->page, 5),
            count($clients),
            5,
            $request->page,
            array('path' => $request->url())
        );

結果
これで1ページ当たり5つで表示され、ページネーションも動作しました。
ちなみに、ここで分割したコレクションをview側では
下記のように記述することで表示されるとのことです。

{{ $clients->links() }}

お役に立てれば幸いです!それでは!

■参考記事

Laravel 5.5 データベース:ペジネーション
https://readouble.com/laravel/5.5/ja/pagination.html

Laravel 5.5 データベース:コレクション
https://readouble.com/laravel/5.5/ja/collections.html

Laravel - ページングを実装するためLengthAwarePaginatorを使ってみた
https://qiita.com/isshi_pg/items/b4215b12f27c1863477a

Laravelで自前の配列をPaginatorに
https://qiita.com/t_n/items/1c9a239da4cf938ae0a8

Laravel 5.4 LengthAwarePaginator
https://stackoverflow.com/questions/43601095/laravel-5-4-lengthawarepaginator

50
48
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
50
48