return в контроллере
-
- Сообщения: 119
- Зарегистрирован: 2014.06.23, 11:44
- Откуда: Украина
return в контроллере
Если в экшн контроллера аяксом пришел запрос из js скрипта то return в этом случае возвращает ответ скрипту? А если мне в экшене надо сделать return render, то что идёт тогда скрипту? Запутался малость
Re: return в контроллере
то что вернет функция render() (ответ)
-
- Сообщения: 119
- Зарегистрирован: 2014.06.23, 11:44
- Откуда: Украина
Re: return в контроллере
Но скрипту может не понравится что вернет render. А можно скрипту сначала вернуть ответ, а потом сделать render?
Re: return в контроллере
ну значит вы должны так сформировать ответ чтобы скрипты "понравилось", можно использовать JSON формат и в нем в одной переменной отдать один ответ, а в другой результат рендера, но 2 ответа на один запрос вам отдать не получится
-
- Сообщения: 119
- Зарегистрирован: 2014.06.23, 11:44
- Откуда: Украина
Re: return в контроллере
Ну, хорошо, если запрос успешен и я просто рендерю вьюху с данными, то в калбек success скрипта что попадет? Html код который отдала вьюха?
Re: return в контроллере
да, сделайте console.log() и посмотрите
Re: return в контроллере
Да. Еще можно разделить запросы на ajax и не ajax и отдавать в callback success что хочется, например json.rosolovsky писал(а): ↑2018.04.01, 00:08 Ну, хорошо, если запрос успешен и я просто рендерю вьюху с данными, то в калбек success скрипта что попадет? Html код который отдала вьюха?
Код: Выделить всё
public function actionCool()
{
$request = Yii::$app->request;
if ($request->isAjax)
{
\Yii::$app->response->format = 'json';
return ['success'];
}
else
{
return $this->render('index');
}
}
Ответственные программисты с высоким уровнем технического долга (c)
-
- Сообщения: 119
- Зарегистрирован: 2014.06.23, 11:44
- Откуда: Украина
Re: return в контроллере
Извиняюсь, а как тогда мне тогда динамически обновлять кусок html кода на странице, например статус корзины которая хранится в сессии?
При загрузке страницы в layout я вывожу кусочек кода
а вот код
и вот при изменении в корзине из конролера я хотел сделать так
но получается этот код идет в js скрипт, и там его конечно можно через js показать на странице, но я думал что можно постредством render или renderPartial фреймворка это сделать.
При загрузке страницы в layout я вывожу кусочек кода
Код: Выделить всё
<?= Yii::$app->view->render('..\cart\minicart.php'); ?>
Код: Выделить всё
<?php
if(isset($_SESSION['cart'])){
echo ('<p>Товаров: '.$_SESSION['cart.qty'].'</p>');
echo ('<p>На сумму: '.$_SESSION['cart.sum'].'</p>');
}
else {
echo('<p> Ваша корзина пуста</p>');
}
?>
Код: Выделить всё
return $this->renderPartial('..\cart\minicart.php');
Re: return в контроллере
render и renderPartial - осуществляют вывод из php в браузер. К JavaScript отношения не имеют. Код выдуман для примера.rosolovsky писал(а): ↑2018.04.01, 09:37 Извиняюсь, а как тогда мне тогда динамически обновлять кусок html кода на странице, например статус корзины которая хранится в сессии?
Работа 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,
]);
}
Код: Выделить всё
// Не используем никаких isset($_SESSION['cart']) - это логика для данных, ее выносим за пределы view (выше в контроллере)
// Получется шаблон, содержащий представление и готовые данные
<p>Товаров: <?= $cartQuantity; ?></p>
<p>На сумму: <?= $cartSum; ?></p>
Код: Выделить всё
<div id="#cart"> <!-- уровень "выше" -->
<!-- вывод данных корзины -->
</div> <!-- /уровень "выше" -->
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,
]);
}
Код: Выделить всё
$(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('Ошибка обновления корзины');
});
});
Код: Выделить всё
<div id="cart">
<p>Количество: {cart.quantity}</p>
<p>На сумму: {cart.sum}</p>
</div>
Последний раз редактировалось nickdenry 2018.04.02, 02:58, всего редактировалось 1 раз.
Ответственные программисты с высоким уровнем технического долга (c)
-
- Сообщения: 119
- Зарегистрирован: 2014.06.23, 11:44
- Откуда: Украина
Re: return в контроллере
nickdenry, вот это расписал. Спасибо!!! Вот по факту у меня и получился третий вариант.
Re: return в контроллере
В "боевом" коде данные для корзины лучше обернуть в модель (не AR-модель), даже для работы с сессиями. AJAX сделать get или post в зависимости от типа операции. Если только получение данных без изменений - лучше get.rosolovsky писал(а): ↑2018.04.01, 18:16 nickdenry, вот это расписал. Спасибо!!! Вот по факту у меня и получился третий вариант.
Ответственные программисты с высоким уровнем технического долга (c)
-
- Сообщения: 119
- Зарегистрирован: 2014.06.23, 11:44
- Откуда: Украина
Re: return в контроллере
Ммм, то есть работать не с сессией напрямую а с моделью? С сессией удобно, фактически данные сессии есть везде, и в контроллере и во вью и в модели. Не надо их гонять туда сюда согласно MVC.
Re: return в контроллере
Основная идея-минимум - собрать в одном месте строковые идентификаторы, это если к текущему частному случаю. Если в общем - избавиться в коде от мест, которые нужно менять многократно. Код, опять же, выдуман для примера.
Т.е. имеем тот же код
Код: Выделить всё
$_SESSION['cart.qty']
Код: Выделить всё
Yii::$app->session->get('cart.qty');
повторяющийся многократно, в модели, контроллере, представлении:С сессией удобно, фактически данные сессии есть везде, и в контроллере и во вью и в модели. Не надо их гонять туда сюда согласно MVC.
Код: Выделить всё
Yii::$app->session->get('cart.qty'); // В AR модели для обработки, например, устанавливаем $_SESSION['cart.qty'] = 5;
Yii::$app->session->get('cart.qty'); // В контроллере по каким-то причинам
Yii::$app->session->get('cart.qty'); // В представлении, для отображения
Поэтому минимально - хелпер.
Код: Выделить всё
<?php
namespace common\helpers;
use Yii;
class CartHelper
{
const CART_QUANTITY = 'cart.qty';
const CART_SUMM = 'cart.sum';
// Получаем количество
public function getQuantity()
{
return Yii::$app->session-get(static::CART_QUANTITY);
}
// Устанавливаем количество
public function setQuantity($quantity)
{
Yii::$app->session->set(static::CART_QUANTITY, $quantity);
}
// Получаем сумму
public function getSum()
{
return Yii::$app->session-get(static::CART_SUMM);
}
// Устанавливаем сумму
public function setSum($sum)
{
Yii::$app->session->set(static::CART_SUMM, $sum);
}
}
?>
Код: Выделить всё
CartHelper::getQuantity();
CartHelper::setQuantity(500);
Код: Выделить всё
<?php
namespace common\models;
use Yii;
class Cart
{
private $quantity;
private $sum;
// Получаем количество
public function getQuantity()
{
return $this->quantity;
}
// Устанавливаем количество
public function getQuantity($quantity)
{
$this->quantity = $quantity;
}
// Получаем сумму
public function getSum()
{
return $this->sum;
}
// Устанавливаем сумму
public function setSum($sum)
{
$this->sum = $sum;
}
}
?>
но в контроллере можно будет возвращать объект целиком, т.е.
Код: Выделить всё
// Данные получаем в контроллере, возвращаем json
// {"cartQantity": 3, "cartSum": 100500}
public function actionDisplayCart
{
// Объект корзины
$cart = new Cart();
// Загрузка, например
$cart->loadFromSession();
// или
$cart->loadFromRedis();
// или
CartLoader::load($cart, <storage>);
// и т.д.
if ($request->isAjax)
{
\Yii::$app->response->format = 'json';
// Возвращаем объект с данными
return $cart;
}
else
{
throw new BadRequestHttpException('Запрос должен осуществляться через AJAX.');
}
}
Ответственные программисты с высоким уровнем технического долга (c)