По мере знакомства с Yii2, я планирую писать небольшие статьи с практическим сравнением Yii и Yii2. Думаю эта информация будет полезна всем, кто хочет как можно быстрее освоиться во второй версии Yii-фреимворка. Сегодня речь пойдет о пейджинации.
$criteria = new CDbCriteria(); ... $count = Post::model()->count($criteria); $pages=new CPagination($count); $pages->pageSize = Yii::app()->params['per_page']; $pages->applyLimit($criteria); $post = Post::model()->findAll($criteria); $this->render('index', array( 'post' => $post, 'pagenator' => $pages, ));
Создаем критерии выбора. С помощью метода count(), считаем сколько записей сможем получить по этим критериям. Создаем объект пейджинации и передаем ему общее число записей. Устанавливаем количество записей на странице (pageSize) и применяем пейджинатор к нашим критериям. В этот момент в критерии добавятся limit и offset в зависимости от текущей старницы (приватная переменная объекта CPagination $_currentPage устанавливается в зависимости от $_GET параметра, задаваемого переменной $pageVar и по умолчанию равного ‘page’)
<?php $this->widget('CLinkPager', array( 'pages' => $pagenator, 'htmlOptions'=> array('class'=>'pagination'), )) ?>
$query = Post::find()->where(...); $countQuery = clone $query; $pages = new Pagination(['totalCount' => $countQuery->count(), 'pageSize' => Yii::$app->params['pageSize']]); $pages->pageSizeParam = false; $post = $query->offset($pages->offset) ->limit($pages->limit) ->orderBy('id desc') ->all(); return $this->render('index', [ 'post' => $post, 'pagenator' => $pages, ] );
Принцип работы с пейджинатором не особо поменялся. Все так же создается объект и передаются такие параметры как общее число записей и число записей на страницу. Зато сильно поменялось применение пейджинатора к запросу. Теперь нужно явно задать offset и limit. На мой взгляд стало лучше, более читабельно и логично. Из дополнительных фишек:
<?php echo LinkPager::widget([ 'pagination' => $pages, 'registerLinkTags' => true ]); ?>
Как видите виджеты тоже поменялись, но на мой взгляд только названием. В остальном настраиваются CSS классы практически как и прежде, но об этом лучше расскажут верстальщики.
registerLinkTags
В доках нет http://www.yiiframework.com/doc-2.0/yii-data-pagination.html
А в коде есть 😉
А что делать если нужна постраничность с фильтром, данные из которого прилетают в post? То есть я выбрал значение на странице в поле формы, нажал «Найти» у меня появился правильный результат выборки и правильная пагинация. Но потом когда я кликаю на следующую страницу, снова получаю весь результат выборки, а не такой как был по фильтру…
В любом случаи нужно как-то передавать условия фильтра на следующую страницу. Например передавать их в GET-параметрах или хранить в сессии. А еще можно сделать hidden форму и отлавливая клик по ссылке пейджинатора — сабмитить эту форму, но это уже совсем извращенный способ 🙂
Все хорошо. потому что систематизировано.
Однако вот интересно — как пагинацию можно подстроить, какие параметры и куда воткнуть.
Типа ‘prevPageLabel’, ‘nextPageLabel’ и пр.
Нигде нет информации что еще туда можно прописать в принципе, и что получится.
Все что касается логики пейджинации — в классе yii\data\Pagination
Все что касается внешнего вида — в классе виджета yii\widgets\LinkPager
Имхо, лучшая документация Yii это исходный код.
А вот есть вопрос на засыпку. Искал и экспериментировал с параметрами пагинации и так не разобрался.
Есть пагинация рбвернутая в pjax и например я перешел на вторую страницу с сылкой такого вида:
http://localhost/customers/index?page=2&per-page=10&_pjax=%23customersTable
После изменений данных контейнер pjax перегружается и отображает первую страницу.
А хочется чтобы оставался там же.
Для yii1.x решение описали здесь http://www.yiiframework.ru/forum/viewtopic.php?t=10822 ,
но для yii2 это не работает 🙁 и ничего дельного найти не получилось. Буду благодарен за совет.
Для yii2 у объекта Pagination есть метод setPage() который выставляет текущую страницу для пейджинатора, так-же как currentPage это делал для yii1.