Qiang Xue
10 years ago
4 changed files with 134 additions and 66 deletions
@ -1,40 +1,73 @@ |
|||||||
ページネーション |
ページネーション |
||||||
================ |
================ |
||||||
|
|
||||||
一つのページに一度に表示するにはデータ数が多すぎる場合に、それぞれ一定数のデータアイテムを含む部分にデータを分割して、一度に一つの部分だけを表示することがよく行われます。 |
一つのページに表示するにはデータの数が多すぎるという場合に、データを複数のページに分割して、それぞれのページでは一部分だけを表示する、という戦略がよく使われます。 |
||||||
このような部分はページと呼ばれますが、それがページネーションという名前の由来です。 |
この戦略が *ページネーション* として知られるものです。 |
||||||
|
|
||||||
あなたが [データウィジェット](output-data-widgets.md) の一つとともに [データプロバイダ](output-data-providers.md) を使っている場合は、ページネーションは既に自動的に設定されて、うまく動作するようになっています。 |
Yii は [[yii\data\Pagination]] オブジェクトを使って、ページネーションのスキームに関する情報を表します。 |
||||||
そうでない場合は、あなたが [[\yii\data\Pagination]] オブジェクトを作成し、[[\yii\data\Pagination::$totalCount|総アイテム数]]、[[\yii\data\Pagination::$pageSize|ページサイズ]]、[[\yii\data\Pagination::$page|現在のページ]] などのデータを代入して、クエリに適用し、そして [[\yii\widgets\LinkPager|リンクページャ]] に与えなければなりません。 |
具体的に言えば、 |
||||||
|
|
||||||
まず最初に、コントローラアクションの中でページネーションオブジェクトを作成し、データを代入します。 |
* [[yii\data\Pagination::$totalCount|totalCount]] データアイテムの総数を指定します。 |
||||||
|
通常、データアイテムの総数は、一つのページを表示するのに必要なデータアイテムの数より、ずっと大きなものになることに注意してください。 |
||||||
|
* [[yii\data\Pagination::$pageSize|pageSize]] 各ページが含むアイテムの数を指定します。 |
||||||
|
デフォルト値は 20 です。 |
||||||
|
* [[yii\data\Pagination::$page|page]] 現在のページ番号 (0 から始まる) を示します。 |
||||||
|
デフォルト値は 0 であり、最初のページを意味します。 |
||||||
|
|
||||||
|
これらの情報を全て定義した [[yii\data\Pagination]] オブジェクトを使って、データの一部分を取得して表示することが出来ます。 |
||||||
|
例えば、データプロバイダからデータを取得する場合であれば、ページネーションによって提供される値によって、それに対応する `OFFSET` と `LIMIT` の句を DB クエリに指定することが出来ます。 |
||||||
|
下記に例を挙げます。 |
||||||
|
|
||||||
```php |
```php |
||||||
function actionIndex() |
use yii\data\Pagination; |
||||||
{ |
|
||||||
$query = Article::find()->where(['status' => 1]); |
// status = 1 である全ての記事を取得する DB クエリを構築する |
||||||
$countQuery = clone $query; |
$query = Article::find()->where(['status' => 1]); |
||||||
$pages = new Pagination(['totalCount' => $countQuery->count()]); |
|
||||||
$models = $query->offset($pages->offset) |
// 記事の総数を取得する (ただし、記事のデータはまだ取得しない) |
||||||
->limit($pages->limit) |
$count = $query->count(); |
||||||
->all(); |
|
||||||
|
// 記事の総数を使ってページネーションオブジェクトを作成する |
||||||
return $this->render('index', [ |
$pagination = new Pagination(['totalCount' => $count]); |
||||||
'models' => $models, |
|
||||||
'pages' => $pages, |
// ページネーションを使ってクエリの OFFSET と LIMIT を修正して記事を取得する |
||||||
]); |
$articles = $query->offset($pages->offset) |
||||||
} |
->limit($pages->limit) |
||||||
|
->all(); |
||||||
``` |
``` |
||||||
|
|
||||||
次に、ビューにおいて、現在のページのモデルを出力し、リンクページャにページネーションオブジェクトを渡します。 |
上記の例で返される記事のページ番号はどうなるでしょう? |
||||||
|
それは `page` という名前のクエリパラメータがリクエストに含まれるかどうかによって決ります。 |
||||||
|
デフォルトでは、ページネーションオブジェクトは [[yii\data\Pagination::$page|page]] に `page` パラメータの値をセットしようと試みます。 |
||||||
|
そして、このパラメータが提供されていない場合には、デフォルト値である 0 が使用されます。 |
||||||
|
|
||||||
|
ページネーションをサポートする UI 要素の構築を容易にするために、Yii はページボタンのリストを表示する [[yii\widgets\LinkPager]] ウィジェットを提供しています。 |
||||||
|
これは、ユーザがページボタンをクリックして、どのページを表示すべきかを指示することが出来るものです。 |
||||||
|
このウィジェットは、ページネーションオブジェクトを受け取って、現在のページ番号が何であるかを知り、何個のページボタンを表示すべきかを知ります。 |
||||||
|
例えば、 |
||||||
|
|
||||||
```php |
```php |
||||||
foreach ($models as $model) { |
use yii\widgets\LinkPager; |
||||||
// ここで $model を表示 |
|
||||||
} |
|
||||||
|
|
||||||
// ページネーションを表示 |
|
||||||
echo LinkPager::widget([ |
echo LinkPager::widget([ |
||||||
'pagination' => $pages, |
'pagination' => $pagination, |
||||||
]); |
]); |
||||||
``` |
``` |
||||||
|
|
||||||
|
UI 要素を手動で構築したい場合は、[[yii\data\Pagination::createUrl()]] を使って、いろんなページに跳ぶ URL を作成することが出来ます。 |
||||||
|
このメソッドは page パラメータを要求し、その page パラメータを含む正しくフォーマットされた URL を作成します。 |
||||||
|
例えば、 |
||||||
|
|
||||||
|
```php |
||||||
|
// 作成される URL が使用すべきルートを指定する |
||||||
|
// 指定しない場合は、現在リクエストされているルートが使用される |
||||||
|
$pagination->route = 'article/index'; |
||||||
|
|
||||||
|
// /index.php?r=article/index&page=100 を表示 |
||||||
|
echo $pagination->createUrl(100); |
||||||
|
|
||||||
|
// /index.php?r=article/index&page=101 を表示 |
||||||
|
echo $pagination->createUrl(101); |
||||||
|
``` |
||||||
|
|
||||||
|
> Tip|ヒント: `page` クエリパラメータの名前をカスタマイズするためには、ページネーションオブジェクトを作成する際に [[yii\data\Pagination::pageParam|pageParam]] プロパティを構成します。 |
||||||
|
@ -1,54 +1,89 @@ |
|||||||
並べ替え |
並べ替え |
||||||
======== |
======== |
||||||
|
|
||||||
表示するデータを一つまたはいくつかの属性に従って並べ替えなければならないことがあります。 |
複数のデータ行を表示する際に、エンドユーザによって指定されるカラムに従ってデータを並べ替えなければならないことがよくあります。 |
||||||
あなたが [データウィジェット](output-data-widgets.md) の一つとともに [データプロバイダ](output-data-providers.md) を使っている場合は、並べ替えはあなたに代って自動的に処理されます。 |
Yii は [[yii\data\Sort]] オブジェクトを使って並べ替えのスキーマに関する情報を表します。 |
||||||
そうでない場合は、[[\yii\data\Sort]] のインスタンスを作成して構成し、クエリに適用しなければなりません。 |
具体的に言えば、 |
||||||
また、[[\yii\data\Sort]] のインスタンスをビューに渡して、属性による並べ替えのためのリンクを作成することが出来ます。 |
|
||||||
|
|
||||||
典型的な使用方法の例を次に示します。 |
* [[yii\data\Sort::$attributes|attributes]] データの並べ替えに使用できる *属性* を指定します。 |
||||||
|
単純で良ければ、[モデルの属性](structure-models.md#attributes) をこの属性とすることが出来ます。 |
||||||
|
また、複数のモデル属性や DB のカラムを結合した合成的な属性を指定することも出来ます。 |
||||||
|
詳細については後述します。 |
||||||
|
* [[yii\data\Sort::$attributeOrders|attributeOrders]] 各属性について、現在リクエストされている並べ替えの方向を指定します。 |
||||||
|
* [[yii\data\Sort::$orders|orders]] 並べ替えの方向をカラムを使う低レベルな形式で示します。 |
||||||
|
|
||||||
|
[[yii\data\Sort]] を使用するためには、最初にどの属性が並べ替え可能であるかを宣言します。 |
||||||
|
次に、現在リクエストされている並べ替え情報を [[yii\data\Sort::$attributeOrders|attributeOrders]] または [[yii\data\Sort::$orders|orders]] から取得して、データのクエリをカスタマイズします。 |
||||||
|
例えば、 |
||||||
|
|
||||||
```php |
```php |
||||||
function actionIndex() |
use yii\data\Sort; |
||||||
{ |
|
||||||
$sort = new Sort([ |
$sort = new Sort([ |
||||||
'attributes' => [ |
'attributes' => [ |
||||||
'age', |
'age', |
||||||
'name' => [ |
'name' => [ |
||||||
'asc' => ['first_name' => SORT_ASC, 'last_name' => SORT_ASC], |
'asc' => ['first_name' => SORT_ASC, 'last_name' => SORT_ASC], |
||||||
'desc' => ['first_name' => SORT_DESC, 'last_name' => SORT_DESC], |
'desc' => ['first_name' => SORT_DESC, 'last_name' => SORT_DESC], |
||||||
'default' => SORT_DESC, |
'default' => SORT_DESC, |
||||||
'label' => 'Name', |
'label' => '氏名', |
||||||
], |
|
||||||
], |
], |
||||||
]); |
], |
||||||
|
]); |
||||||
$models = Article::find() |
|
||||||
->where(['status' => 1]) |
$articles = Article::find() |
||||||
->orderBy($sort->orders) |
->where(['status' => 1]) |
||||||
->all(); |
->orderBy($sort->orders) |
||||||
|
->all(); |
||||||
return $this->render('index', [ |
|
||||||
'models' => $models, |
|
||||||
'sort' => $sort, |
|
||||||
]); |
|
||||||
} |
|
||||||
``` |
``` |
||||||
|
|
||||||
ビューにおいては、 |
上記の例では、[[yii\data\Sort|Sort]] オブジェクトに対して二つの属性が宣言されています。 |
||||||
|
すなわち、`age` と `name` です。 |
||||||
|
|
||||||
|
`age` 属性は `Article` アクティブレコードクラスの `age` 属性に対応する *単純な* 属性です。 |
||||||
|
これは、次の宣言と等価です。 |
||||||
|
|
||||||
```php |
```php |
||||||
// 並べ替えのアクションに導くリンクを表示 |
'age' => [ |
||||||
|
'asc' => ['age' => SORT_ASC], |
||||||
|
'desc' => ['age' => SORT_DESC], |
||||||
|
'default' => SORT_ASC, |
||||||
|
'label' => Inflector::camel2words('age'), |
||||||
|
] |
||||||
|
``` |
||||||
|
|
||||||
|
`name` 属性は `Article` の `first_name` と `last_name` によって定義される *合成的な* 属性です。 |
||||||
|
これは次のような配列構造を使って宣言されています。 |
||||||
|
|
||||||
|
- `asc` および `desc` の要素は、それぞれ、この属性を昇順および降順に並べ替える方法を指定します。 |
||||||
|
この値が、データの並べ替えに使用されるべき実際のカラムと方向を表します。 |
||||||
|
一つまたは複数のカラムを指定して、単純な並べ替えや合成的な並べ替えを示すことが出来ます。 |
||||||
|
- `default` 要素は、最初にリクエストされたときの属性の並べ替えに使用されるべき方向を指定します。 |
||||||
|
デフォルト値は昇順です。 |
||||||
|
つまり、以前に並べ替えられたことがない状態でこの属性による並べ替えをリクエストすると、この属性の昇順に従ってデータが並べ替えられることになります。 |
||||||
|
- `label` 要素は、並べ替えのリンクを作成するために [[yii\data\Sort::link()]] を呼んだときに、どういうラベルを使用すべきかを指定するものです。 |
||||||
|
設定されていない場合は、[[yii\helpers\Inflector::camel2words()]] が呼ばれて、属性名からラベルが生成されます。 |
||||||
|
ラベルは HTML エンコードされないことに注意してください。 |
||||||
|
|
||||||
|
> Info|情報: [[yii\data\Sort::$orders|orders]] の値をデータベースのクエリに直接に供給して、`ORDER BY` 句を構築することが出来ます。 |
||||||
|
データベースのクエリが認識できない合成的な属性が入っている場合があるため、[[yii\data\Sort::$attributeOrders|attributeOrders]] を使ってはいけません。 |
||||||
|
|
||||||
|
[[yii\data\Sort::link()]] を呼んでハイパーリンクを生成すれば、それをクリックして、指定した属性によるデータの並べ替えをリクエストすることが出来るようになります。 |
||||||
|
[[yii\data\Sort::createUrl()]] を呼んで並べ替えを実行する URL を生成することも出来ます。 |
||||||
|
例えば、 |
||||||
|
|
||||||
|
```php |
||||||
|
// 生成される URL が使用すべきルートを指定する |
||||||
|
// これを指定しない場合は、現在リクエストされているルートが使用される |
||||||
|
$sort->route = 'article/index'; |
||||||
|
|
||||||
|
// 氏名による並べ替えと年齢による並べ替えを実行するリンクを表示 |
||||||
echo $sort->link('name') . ' | ' . $sort->link('age'); |
echo $sort->link('name') . ' | ' . $sort->link('age'); |
||||||
|
|
||||||
foreach ($models as $model) { |
// /index.php?r=article/index&sort=age を表示 |
||||||
// ここで $model を表示 |
echo $sort->createUrl('age'); |
||||||
} |
|
||||||
``` |
``` |
||||||
|
|
||||||
上記においては、並べ替えをサポートする二つの属性、すなわち、`name` と `age` を宣言しています。 |
[[yii\data\Sort]] は、リクエストの `sort` クエリパラメータをチェックして、どの属性による並べ替えがリクエストされたかを判断します。 |
||||||
並べ替えの情報を Article クエリに渡して、クエリ結果が Sort オブジェクトで指定された順序に従って並べ替えられるようにしています。 |
このクエリパラメータが存在しない場合のデフォルトの並べ替え方法は [[yii\data\Sort::defaultOrder]] によって指定することが出来ます。 |
||||||
ビューにおいては、二つのハイパーリンクを表示して、対応する属性によって並べ替えられたデータを表示するページへ移動できるようにしています。 |
また、[[yii\data\Sort::sortParam|sortParam]] プロパティを構成して、このクエリパラメータの名前をカスタマイズすることも出来ます。 |
||||||
|
|
||||||
[[yii\data\Sort|Sort]] クラスは、リクエストで渡されたパラメータを自動的に取得して、それに応じて並べ替えのオプションを調整します。 |
|
||||||
パラメータは [[yii\data\Sort::$params|$params]] プロパティを構成して調整することが出来ます。 |
|
||||||
|
Loading…
Reference in new issue