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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.