Почему метод init виджета вызывается не только при инициализации?

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Закрыто
i-programmer
Сообщения: 101
Зарегистрирован: 2015.08.24, 18:50

Почему метод init виджета вызывается не только при инициализации?

Сообщение i-programmer »

Есть виджет, в котором отображается `GridView`, обёрнутый в Pjax. У грида есть пагинация. В виджете написано свойство и заполняется в методе `init` и передается в методе `run` в темплейт:

Код: Выделить всё

    
public $myUid;

public function init() {
    parent::init();
    $this->myUid = uniqid();
}

public function run() { 
    // Много кода
    return $this->render('widget-template', [   
        'myUid' => $this->myUid,    
        // Другие переменные
    ]);
}
Представление:

Код: Выделить всё

<?php Pjax::begin(['id' => 'widget-grid']); ?>

<?= $myUid .'<br>'; ?>

<?= GridView::widget([
    'dataProvider' => $dataProvider,
    'columns' => $gridColumns,  
]); ?>

<?php Pjax::end(); ?>
В итоге, при клике на пагинации в гриде я вижу не только изменения в таблице, но и меняющееся значение в переменной `$myUid`.

Вопрос: Почему? Разве `init` не должен нести только функцию инициализации и больше не вызываться никогда вообще? Я представлял, что в таком случае должен работать только метод `run`. Почему так происходит?

Дополнительный вопрос
: Есть ли в виджете такой метод, который действительно вызывается только раз? Который не дергается при ajax запросах?
chesar
Сообщения: 514
Зарегистрирован: 2013.04.10, 17:49

Re: Почему метод init виджета вызывается не только при инициализации?

Сообщение chesar »

Php не сохраняет состояния между запросами, поэтому при новом запросе на сервер, приложение заново стартует в index.php и все компоненты инициализируются заново.
Для сохранения состояния между запросами в рамках одного пользователя используют сессии.
i-programmer
Сообщения: 101
Зарегистрирован: 2015.08.24, 18:50

Re: Почему метод init виджета вызывается не только при инициализации?

Сообщение i-programmer »

chesar писал(а): 2019.06.27, 22:45 Php не сохраняет состояния между запросами, поэтому при новом запросе на сервер, приложение заново стартует в index.php и все компоненты инициализируются заново.
Для сохранения состояния между запросами в рамках одного пользователя используют сессии.
Да, я про состояние и новый старт index.php тоже подумал уже. И про хранение состояние в сессии тоже думал и уже пробовал, но ничего не выходит. Я не понимаю что и где нужно прописать, чтобы корректный идентификатор был и там и там. И при этом работало.

Костыли в виде

Код: Выделить всё

$isAjax = \Yii::$app->request->isAjax;
$isPjax = \Yii::$app->request->headers->get('x-pjax');
if (!$isAjax && !$isPjax) {
	
}
if ($isAjax && !$isPjax) {
	
}
if ($isAjax && $isPjax) {
	
}
писал, где оперировал сессией. Но всё пока впустую
chesar
Сообщения: 514
Зарегистрирован: 2013.04.10, 17:49

Re: Почему метод init виджета вызывается не только при инициализации?

Сообщение chesar »

Код: Выделить всё

$key = __CLASS__ . '#uid';
$this->myUid = Yii::$app->session->get($key);
if ($this->myUid === null) {
    $this->myUid = uniqid();
    Yii::$app->session->set($key, $this->myUid);
}
Таким образом, при первом посещении $this->myUid будет равен null, переменной будет присвоено значение выданное функцией uniqid() и записано в сессию. При последующих обращениях к сайту, значение будет браться из сессии.
i-programmer
Сообщения: 101
Зарегистрирован: 2015.08.24, 18:50

Re: Почему метод init виджета вызывается не только при инициализации?

Сообщение i-programmer »

chesar писал(а): 2019.06.28, 09:31

Код: Выделить всё

$key = __CLASS__ . '#uid';
$this->myUid = Yii::$app->session->get($key);
if ($this->myUid === null) {
    $this->myUid = uniqid();
    Yii::$app->session->set($key, $this->myUid);
}
Таким образом, при первом посещении $this->myUid будет равен null, переменной будет присвоено значение выданное функцией uniqid() и записано в сессию. При последующих обращениях к сайту, значение будет браться из сессии.

А это точно будет работать для большого количества виджетов на странице? Потому что суть виджетов как раз в том, что их можно многократно задействовать где только можно. Именно в этот момент начинаются танцы с бубном. С текущим вопросом мне всё понятно, поэтому я нарисовал костыль и описал в другом вопросе viewtopic.php?f=19&t=51211
Возможно вы сможете помочь.
Спасибо за ответы здесь тоже.
Закрыто