rosolovsky писал(а): ↑2018.04.01, 09:37
Извиняюсь, а как тогда мне тогда динамически обновлять кусок html кода на странице, например статус корзины которая хранится в сессии?
render и renderPartial - осуществляют вывод из php в браузер. К JavaScript отношения не имеют. Код выдуман для примера.
Работа render:
1. Статическая реализация (просто показываем страницу и обновляем целиком). Вывод с помощью php, будь то с Yii(2) или нет. Полагаю, что используем Yii2.
В контроллере, отвечающем за вывод страницы имеем код
Код: Выделить всё
// Данные получаем в контроллере, передаем в view
public function actionDisplayCart
{
// Получаем количество и сумму из сессии
$cartQuantity = Yii::$app->session->get('cart.qty');
$cartSum = Yii::$app->session->get('cart.sum');
// Выводим в браузер файл views/<имя_контроллера>/cart.php
return $this->render('cart', [
'cartQuantity' => $cartQuantity,
'cartSum' => $cartSum,
]);
}
Код view
Код: Выделить всё
// Не используем никаких isset($_SESSION['cart']) - это логика для данных, ее выносим за пределы view (выше в контроллере)
// Получется шаблон, содержащий представление и готовые данные
<p>Товаров: <?= $cartQuantity; ?></p>
<p>На сумму: <?= $cartSum; ?></p>
Теперь при переходе по адресу action DisplayCart, т.е. в браузере при открытии URL /<имя_контроллера>/display-cart показывается страница с кодом указанного view, ко всему прочему обернутым в шаблон layout или другой view, например.
Код: Выделить всё
<div id="#cart"> <!-- уровень "выше" -->
<!-- вывод данных корзины -->
</div> <!-- /уровень "выше" -->
Т.е. мы можем обновлять информацию о корзине простой перезагрузкой страницы -
данные генерируются php и передаются непосредственно в браузер.
2. Динамическая реализация.
Т.к. перезагружать страницу каждый раз неудобно, используем AJAX для обновления корзины, т.е. отправляем XMLHttpRequest на сервер, обновляем не всю страницу, а только часть.
Самый простой способ - jQuery.
меняем код action для вывода view без шаблона
Код: Выделить всё
// Данные получаем в контроллере, передаем в view
public function actionDisplayCart
{
$cartQuantity = Yii::$app->session->get('cart.qty');
$cartSum = Yii::$app->session->get('cart.sum');
// Заменяем render на renderPartial
return $this->renderPartial('cart', [
'cartQuantity' => $cartQuantity,
'cartSum' => $cartSum,
]);
}
Отправляем POST запрос к тому же action
Код: Выделить всё
$(document).ready(function(){
$.post(
'/<имя_контроллера>/display-cart',
{
// параметры, если есть
},
).done(function(data) {
// В содержимое элемента с id "cart" выводим ответ сервера.
// В браузер попадет тот же вывод, что представлен в шаблоне views/<имя_контроллера>/cart.php
$('#cart').html(data);
}).fail(function() {
$('#cart').html('Ошибка обновления корзины');
});
});
В результате содержимое тэга
Код: Выделить всё
<div id="cart"><!-- содержимое тут --></div>
заменится выводом
Код: Выделить всё
<p>Товаров: <?= $cartQuantity; ?></p>
<p>На сумму: <?= $cartSum; ?></p>
с подставленными значениями количества и суммы
В этом случае данные
генерируются php, передаются в браузер, но частично и за обновление на странице отвечает JavaScript.
3. Более продвинутая реализация, замена только данных.
Контроллер
Код: Выделить всё
// Данные получаем в контроллере, возвращаем json
// {"cartQantity": 3, "cartSum": 100500}
public function actionDisplayCart
{
$cartQuantity = Yii::$app->session->get('cart.qty');
$cartSum = Yii::$app->session->get('cart.sum');
$request = Yii::$app->request;
if ($request->isAjax)
{
\Yii::$app->response->format = 'json';
// Возвращаем массив с ключами
return [
'cartQuantity' => $cartQuantity,
'cartSum' => $cartSum,
];
}
else
{
throw new BadRequestHttpException('Запрос должен осуществляться через AJAX.');
}
}
Представление выглядит как
Код: Выделить всё
<div id="cart">
<p>Количество: <span class="quantity">0</span></p>
<p>На сумму: <span class="sum">0</span></p>
</div>
Код: Выделить всё
$(document).ready(function(){
$.post(
'/<имя_контроллера>/display-cart',
{
// параметры, если есть
},
).done(function(data) {
// Меняем только данные
$('#cart .quantity').html(data.cartQuantity);
$('#cart .sum').html(data.cartSum);
}).fail(function() {
$('#cart').html('Ошибка обновления корзины');
});
});
Для этого способа придумано множество библиотек, которые автоматически подставляют ответ сервера сразу в html шаблон, например в таком формате
Код: Выделить всё
<div id="cart">
<p>Количество: {cart.quantity}</p>
<p>На сумму: {cart.sum}</p>
</div>
и т.д.