Yii2: Вникаем в Pjax

regular request vs pjax requestПопулярный ныне js фреймворк jQuery оброс большим количеством разнообразных плагинов. Одним из таких плагинов является pjax, позволяющий легко создавать веб приложения с использованием связки ajax и pushState. Эта технология позволяет после нажатия ссылки или submit на форме, отправить на сервер специальный запрос и получить в ответ только то содержимое, которое необходимо обновить на странице, затем pjax заменяет старое содержимое новым и добавляет в историю браузера и адресную строку актуальную url ссылку, без обновления всей страницы.

Обычный запрос каждый раз полностью перезагружает страницу, а pjax может запросить у сервера только нужную часть содержимого.

Фреймворк Yii 2.0 содержит pjax виджет, использование которого не должно вызвать затруднений даже у начинающих.

Сначала укажем пространство имен виджета pjax.

Теперь достаточно обернуть нужную область виджетом.

Так же, возможна настройка виджета:

  • выбор ссылок или форм, которые будут обрабатываться через pjax;
  • указание url ссылки, которая должна быть помещена в историю и адресную строку браузера;
  • период времени, через который страница должна быть обновлена целиком, в случае отсутствия ответа;
  • прокрутка страницы, в случае необходимости.

Примеры использования pjax в yii2

Вы можете скачать исходные коды примеров к этой статье с битбакета.

Обновление данных

Давайте рассмотрим самый простой пример. Допустим, на странице имеются какие-нибудь данные, которые нужно обновлять при нажатии ссылки. Для примера, отобразим текущее время на сервере. Демонстрация.

обновление данных yii2 и pjax

Сначала рассмотрим представление и ту часть его, что нужно обновлять динамически. Используя теги виджета  <?php Pjax::begin(); ?> и  <?php Pjax::end(); ?>, указываем динамическое содержимое. Теперь любая ссылка или форма внутри виджета будет обрабатываться через pjax.

Действие index только лишь формирует данные $time для отображения в представлении.

Не забывайте добавить  use yii\widgets\Pjax; в начале файла представления.

Автоматическое обновление данных на странице

В случае необходимости обновления данных на странице при наступлении какого-нибудь события или по таймеру, нужно добавить, всего лишь, пару строк js кода. Рабочий пример.

Этот код будет имитировать нажатие кнопки «Обновить» на странице каждые три секунды. Нужно только указать идентификатор кнопки 'id' => 'refreshButton'. При необходимости, можно скрыть кнопку, указав соответствующий css класс:  'class' => 'hidden'.

Навигация

В данном примере мы рассмотрим использование нескольких ссылок на разные контроллеры, возвращающие разные данные. Код аналогичен первому примеру, за исключением того, что здесь используются две кнопки. Рабочий пример.

обновление данных yii2 и pjax 02

Два представления отображают одно представление с разными данными.

Несколько независимых блоков

При необходимости, можно разместить на странице несколько виджетов pjax. Они будут работать независимо друг от друга и обновлять только данные внутри себя. Рабочий пример.

обновление данных yii2 и pjax

Рассмотрим представление. Два pjax виджета легко уживаются по-соседству в одном представлении.

И соответствующее действие.

В целях упрощения примера, приведен не самый оптимальный образец кода. В данном случае, при нажатии на любую из кнопок, действие генерирует и хеш и ключ, и передает оба этих значения в представление. Можно использовать два действия и два дополнительных дочерних представления. Тогда вызывая дополнительное представление из основного  <?= $this->render('_randomKey', ['randomKey' => $randomKey]); ?>, мы отобразим их из соответствующего действия.

Pjax формы в Yii2

Еще один отличный пример — использование форм совместно с pjax — отобразим хеш строки из формы. Рабочий пример.

обновление данных yii2 и pjax

В представлении форма с текстовым полем и кнопкой обернуты виджетом pjax.

В действии тоже нет ничего необычного.

Отключение pushState

В некоторых случаях, необходимо вручную отключить pushState. В данном случае, данные будут обновлены, а url в браузере не изменится. Рабочий пример.

обновление данных yii2 и pjax

Представление содержит только две ссылки и счетчик. Для упрощения примера, значение счетчика будем хранить в сессии. Реальные системы голосования устроены на много сложнее, но эта тема выходит за рамки этой статьи. Для отключения pushState, указываем в параметрах виджета в открывающем методе  'enablePushState' => false.

Контроллер содержит три действия. Первое просто отображает представление. Другие два изменяют значение счетчика в сессии и отображают представление.

Сортировка и пагинация gridview в yii2 используя pjax

Виджет GridView в Yii 2.0 был создан с расчетом на динамическое обновление данных, сортировку и пагинацию с использованием pjax. Достаточно просто обернуть gridview в pjax в представлении, никакие изменения контроллера не понадобятся. Рабочий пример.

yii2 gridview и pjax

Заключение

Виджет pjax очень полезен в большинстве случаев. Если с запросом пойдет что-то не так, он может просто перезагрузить страницу целиком. Ссылки на странице можно по-прежнему открывать в новом окне. Pjax стал отличной заменой  CHtml::ajaxLink из Yii первой версии.

В тоже время, методика работы pjax не оптимальна, он оперирует тяжелыми запросами с html кодом. При необходимости, для создания более легких и быстрых веб приложений, нужно использовать js mvc феймворки (например angularjs), jQuery или чистый js. Для этого достаточно отделить данные от представлений при помощи ajax.

Yii2: Вникаем в Pjax: 9 комментариев

  1. Здравствуйте!
    А как использовать pjax внутри собственного виджета?
    У меня имеется страница, которая генерирует в предсавлении публикует множество разных виджетов. Разные виджеты имеют или не имеют свои pjax обертки с разными обработчиками при нажатии на ссылку для обновления.

    Но ведь у виджетов нет контроллеров, которые я мог бы вызвать через ссылку.

    А впихивать акшены в контроллеры на все типы виджетов — недопустимо, не для того я виджеты создавал, чтобы логику их работы опять описывать в контроллере.

  2. Обновление страницы яваскриптом не актуально

    «В случае необходимости обновления данных на странице при наступлении какого-нибудь события или по таймеру, нужно добавить, всего лишь, пару строк js кода.»

    Это можно сделать html тегом:

    Вот пример для простой перезагрузки страницы, через определенный интервал времени:

    где 10 — интервал обновления страницы в секундах.
    Вот пример для перевода посетителя на другую страницу (сайт), через определенное время:

    1. Всмысле не актуально? HTML вообще не должен определять поведение, его задача только представление информации. Такие вещи как редирект и обновление страницы или ее части — поведение.

      Кроме того в статье вообще идет речь об обновлении отдельного элемента страницы, без ее полной перезагрузки.

      Вещь надо сказать, тоже не слишком передовая, с учетом всяких Backbone и Angular, которые гоняют между клиентом и сервером только данные в json, но тоже имеет право на жизнь, так как весьма быстро реализуемаю

  3. в комментах ограничение на колво символов ? а где это указанно? продолжу:

    где после URL указывается страница (сайт), куда нужно перенаправить посетителя.

  4. Все заработало, благодаря опции data-pjax! Спасибо большое! Но почему не выводится флеш?

    true]) ?>

    session->hasFlash(‘success’) ? Yii::$app->session->getFlash(‘success’) : null ?>

  5. У кого-нибудь получилось генерировать отдельно строку и ключ в примере «Несколько независимых блоков»? Можете кинуть код посмотреть, а то я не совсем понял, как это сделать.

  6. Скажите, что делать, если страница обновляется?
    Если указываю url — ‘site/index’
    Если просто ‘#’ — не обновляется страница, но и данные не обновляются.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *