Magento 2: Передача переменных из действия контроллера в «View»

12

В Magento 1, если вы хотите передать данные из действия вашего контроллера в «представление» (т. Е. Блок в макете, вы можете)

  1. Добавить значение / объект в глобальный реестр через Mage::register

  2. Непосредственная выборка объекта блока и установка свойств данных для извлеченного объекта блока после запуска loadLayout

  3. Вызовите методы для блочных объектов в phtmlфайлах, и пусть блочные объекты используют слой модели / базы данных для чтения данных, ранее сохраненных в действии контроллера

Использование методов блочных объектов для чтения из базы данных по-прежнему работает в Magento 2, что подходит для определенных видов операций. Тем не мение,

  1. В Magento 2 больше нет глобального реестра (или есть?)

  2. Система макетов теперь работает, создавая объект страницы через фабрику, и вы не можете получить ссылки на блоки так же, как в Magento 1

Возможно ли в Magento 2 передавать данные непосредственно из действия контроллера в представление? Или это слишком прямой образец для храброго нового мира Design Pattern ™ от Magento? Если это слишком прямой шаблон, что делать, если есть некоторая вычисленная информация, которую мы хотим отобразить в шаблоне, но не хотим сохранять эту информацию в системе с состоянием (то есть мы не хотим сохранять ее в база данных)

Я могу придумать несколько разных способов взломать это вместе, но мне интересно, как Magento 2 хочет , чтобы вы это делали.

Примечание : я понимаю, что можно получить экземпляр блока в действии контроллера, используя что-то вроде этого

$resultPage = $this->resultPageFactory->create();    
$block = $resultPage->getLayout()->getBlock('catalog.wysiwyg.js');        

var_dump(spl_object_hash($block));

Код ядра Magento 2 делает это часто. Однако - блочный объект, извлеченный в объекте контроллера, кажется, отличается от того, который доступен в phtmlшаблоне с помощью либо, $thisлибо $block(прежний ( $this) представляется объектом, который фактически отображает шаблон, тогда как более поздний ( $block) выглядит как экземпляр типа блока Magento).

#File: path/to/template.phtml
var_dump(spl_object_hash($block));
var_dump(spl_object_hash($this));

Я говорю «кажется», потому что, если я устанавливаю данные в методе действия контроллера, они не доступны в phtmlшаблоне - и если я сравниваю spl_object_hashрезультаты выше, я получаю три разных хэша. Тем не менее, я достаточно новичок во всем этом, что вышеупомянутое может быть какой-то другой ошибкой, которую я сделал - поэтому, если вы смогли установить данные для блоков и извлечь их в шаблоне, я бы хотел услышать об этом !

Алан Сторм
источник

Ответы:

17

Что касается # 1, реестр все еще существует, очень похоже на то, что вы знаете из Magento 1. Он просто перемещен. Видеть:\Magento\Framework\Registry

Добавьте его в свой конструктор с помощью внедрения зависимостей, и тогда вы сможете использовать свои привычные методы $registry->register($key, $value)и $registry->registry($key)методы для хранения / доступа к данным.

Я бы порекомендовал покопаться в пространстве имен \ Magento \ Framework, если вы этого еще не сделали. Многое из того, что было доступно из Mage или App прежде, все еще там, просто разделено.

Что касается лучших практик, я не могу ответить на этот вопрос, но я ожидаю, что ответ будет заключаться в том, чтобы сохранить как можно больше логики от контроллера. Глядя на ядро, вероятно, ваш лучший выбор. Например, см. Страницу редактирования адреса клиента: Базовый контроллер ; обширный блок - в том числе вытащить адрес ID и загрузить, если необходимо. Они обрабатывают это прямо в блоке; они не делают это в контроллере, а затем передают его.

Райан Херр
источник
2
Хитрость, конечно, заключается в том, чтобы знать, какие части ядра нужно смотреть, а какие игнорировать :) Спасибо за указатели, +1 за полезную информацию!
Алан Шторм
1
+1 за последний абзац. Если вам нужно поделиться некоторым вычисленным значением, поместите расчетное поведение в отдельный объект и вызовите его из блоков, которым требуется это значение. Реестр не рекомендуется, потому что это глобальное изменяемое состояние, и вы никогда не уверены, что вы получите оттуда. Прямая адресация блоков из действия также не рекомендуется, потому что вы никогда не уверены, присутствует ли блок на странице (макет может убить его)
Антон Криль
@AntonKril как насчет помощников рендера страниц? Помощник страницы CMS, помощник представления продукта, предназначены ли они для отделения рендеринга от HTTP-запроса?
Иван Чепурный
5

Вы не должны передавать переменные из действия контроллера в представление. Используйте блок для передачи Переменных в Вид (механизм шаблонов).

Канди
источник
Почему? Как можно передать параметры get / post из блока в просмотр? Разве большинство логики не передает их с контроллера на просмотр?
LucScu
Использовать объект запроса в блоках. Если вы заблокируете получение данных от контроллера через реестр, вы не сможете использовать его с другими контроллерами. Это называется временная связь и ее плохие практики
Канди
Я использую $ block-> assign () для передачи параметров запроса от контроллера к блоку. Это тоже плохие практики?
LucScu
Прямая адресация блоков от действия также не рекомендуется, потому что вы никогда не уверены, присутствует ли блок на странице.
Канди
В моем случае я уверен, потому что это нестандартный сценарий, когда контроллер, макет и блок контролируются только моим кодом, поэтому я считаю, что параметры запроса логической передачи от контроллера к блоку. Спасибо за ваши ответы!
LucScu