В 14-ом уроке мы изучим одну из важных тем для создания современных веб-приложений, это работу с AJAX в Yii 2. AJAX (Asynchronous JavaScript and XML) позволяет обмениваться данными с сервером без перезагрузки страницы, что делает интерфейсы быстрыми и отзывчивыми. В этом уроке я расскажу, как отправлять AJAX-запросы, обрабатывать их в контроллерах, динамически обновлять контент и реализовать подгрузку данных «на лету».
Отправка AJAX-запросов в Yii 2
Yii 2 предоставляет удобные инструменты для работы с AJAX. Основной механизм строится вокруг JavaScript-библиотеки yii.js, которая уже включена в стандартные шаблоны фреймворка. Эта библиотека добавляет обработчики событий для элементов с атрибутами data-method или data-*, связанными с AJAX.
Как это работает?
Допустим, у нас есть кнопка, при нажатии на которую нужно отправить запрос на сервер. Вместо обычной формы или ссылки мы можем использовать AJAX. Для этого добавим кнопке атрибут data-method="post" и укажем URL через data-url:
use yii\helpers\Url; // В представлении: echo Html::button('Обновить данные', [ 'class' => 'btn btn-primary', 'data-url' => Url::to(['site/refresh']), 'data-method' => 'POST', 'id' => 'refreshButton' ]);
Yii автоматически «поймает» такой элемент и отправит AJAX-запрос при клике. Но если вы хотите больше контроля, можно использовать jQuery напрямую:
$('#refreshButton').on('click', function() { $.ajax({ url: $(this).data('url'), method: 'POST', success: function(response) { console.log('Ответ сервера:', response); } }); });
Всегда проверяйте, подключен ли в вашем шаблоне yii.js (обычно он добавляется через AppAsset). Без него атрибуты data-* не сработают.
Обработка AJAX в контроллере
Теперь разберемся, как обрабатывать AJAX-запросы на стороне сервера. Yii 2 упрощает эту задачу благодаря методу Yii::$app->request->isAjax.
Пример контроллера:
Предположим, у нас есть действие refresh, которое должно вернуть JSON с данными:
namespace app\controllers; use Yii; use yii\web\Controller; class SiteController extends Controller { public function actionRefresh() { if (Yii::$app->request->isAjax) { $data = ['time' => date('H:i:s'), 'message' => 'Данные обновлены!']; return $this->asJson($data); } throw new \yii\web\ForbiddenHttpException('Доступ запрещен'); } }
Что здесь происходит?
- Проверяем, является ли запрос AJAX-ом.
- Если да, то подготавливаем данные и возвращаем их в формате JSON.
- Если нет, то выбрасываем ошибку (для безопасности).
Важно:
- Используйте
return $this->asJson(), а неecho json_encode(). Yii автоматически установит правильные заголовки. - Для работы с AJAX-формами используйте
ActiveForm::validate()это упростит валидацию без перезагрузки страницы.
Обновление данных без перезагрузки страницы
Самый частый сценарий использования AJAX это динамическое обновление контента. Давайте создадим пример: список комментариев, который обновляется после добавления нового.
Шаг 1. Форма для комментария
Создадим форму с AJAX-валидацией:
use yii\widgets\ActiveForm; $form = ActiveForm::begin([ 'id' => 'comment-form', 'enableAjaxValidation' => true, 'validationUrl' => Url::to(['comment/validate']) ]); echo $form->field($model, 'text')->textarea(); echo Html::submitButton('Отправить', ['class' => 'btn btn-success']); ActiveForm::end();
Шаг 2. Действие в контроллере
Добавим обработчик для сохранения комментария:
public function actionCreateComment() { $model = new Comment(); if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) { if ($model->save()) { return $this->asJson(['success' => true, 'html' => $this->renderPartial('_comment', ['comment' => $model])]); } } return $this->asJson(['success' => false]); }
Шаг 3. Обновление списка
В JavaScript добавим обработчик успешного ответа:
$('#comment-form').on('beforeSubmit', function(e) { e.preventDefault(); $.ajax({ url: $(this).attr('action'), method: 'POST', data: $(this).serialize(), success: function(response) { if (response.success) { $('#comments-list').append(response.html); $('#comment-form')[0].reset(); } } }); });
Результат:
Пользователь вводит комментарий, отправляет форму, комментарий мгновенно появляется в списке без перезагрузки страницы.
Пример: динамическая подгрузка контента
Реализуем бесконечную ленту, которая подгружает посты при прокрутке до конца страницы.
Шаг 1. Добавим блок для контента
<div id="posts-container"></div> <div id="loading" style="display: none;">Загрузка...</div>
Шаг 2. Настроим JavaScript
let page = 1; let isLoading = false; $(window).on('scroll', function() { if ($(window).scrollTop() + $(window).height() >= $(document).height() - 100 && !isLoading) { isLoading = true; $('#loading').show(); $.ajax({ url: '/post/list', data: {page: page}, success: function(response) { if (response.html) { $('#posts-container').append(response.html); page++; } isLoading = false; $('#loading').hide(); } }); } });
Шаг 3. Действие для подгрузки
public function actionList($page = 1) { $perPage = 10; $posts = Post::find()->offset(($page - 1) * $perPage)->limit($perPage)->all(); if (empty($posts)) { return $this->asJson(['html' => '']); } $html = $this->renderPartial('_posts', ['posts' => $posts]); return $this->asJson(['html' => $html]); }
Итог:
При прокрутке страницы каждые 10 постов подгружаются автоматически. Пользователь не видит перезагрузок, контент появляется плавно.
Практические задачи
Чтобы закрепить материал, выполните следующие задания:
- AJAX-валидация формы
Создайте форму регистрации с AJAX-валидацией. Проверяйте уникальность email без перезагрузки страницы. - Кнопка «Нравится»
Реализуйте кнопку, которая увеличивает счетчик лайков у статьи. Используйте AJAX для отправки запроса. - Динамический поиск
Сделайте поле поиска, которое показывает результаты по мере ввода текста (с задержкой 300 мс). - Подгрузка товаров
На странице каталога реализуйте подгрузку товаров при прокрутке. Добавьте анимацию загрузки.
Пример кода: Кнопка «Нравится»
Представление:
echo Html::button('❤️ Нравится', [ 'class' => 'like-btn', 'data-post-id' => $post->id, 'data-url' => Url::to(['post/like']), ]);
JavaScript:
$('.like-btn').on('click', function() { let $button = $(this); $.ajax({ url: $button.data('url'), method: 'POST', data: {postId: $button.data('post-id')}, success: function(response) { if (response.success) { $button.text('❤️ ' + response.likes); } } }); });
Контроллер:
public function actionLike() { $postId = Yii::$app->request->post('postId'); $post = Post::findOne($postId); $post->updateCounters(['likes' => 1]); return $this->asJson([ 'success' => true, 'likes' => $post->likes ]); }
Мы разобрали основы работы с AJAX в Yii 2, от отправки запросов до динамического обновления интерфейса. Теперь вы можете создавать современные приложения с плавными переходами и интерактивными элементами. Не забывайте тестировать код и обрабатывать ошибки, это сделает ваши проекты надежными.
Если вы хотите глубже изучить Yii 2, посмотрите полный курс с уроками по Yii 2 для начинающих. Там вы найдете еще больше примеров, проектов и лайфхаков!
Поддержка автора осуществляется с помощью специальной формы ниже, предоставленной сервисом «ЮMoney». Все платёжные операции выполняются на защищённой странице сервиса, что обеспечивает их корректность и полную безопасность.


