Magento - передача данных между контроллером и блоком - PullRequest
46 голосов
/ 24 октября 2010

Действительно быстрый и простой вопрос, но я не могу найти достойного ответа на этот вопрос - Каков наилучший способ передачи данных из контроллера в блок в Magento.

Если это имеет значение, я загружаю макет следующим образом:

 $this->loadLayout(array('default', 'myModule_default'));

    $this->_initLayoutMessages('customer/session')
         ->_initLayoutMessages('catalog/session')
         ->renderLayout();

Я должен добавить, что я использую реестр следующим образом:

В контроллере:

Mage::register('data', $data);

В блоке:

$data = Mage::registry('data');

Не уверен, что это лучший способ сделать это.

Ответы [ 6 ]

83 голосов
/ 24 октября 2010

Ты не.

В MVC-подходе Magento контроллер не несет ответственности за установку переменных для представления (в случае Magento представление - это Layout и blocks). Контроллеры устанавливают значения для Моделей, а затем Блоки считывают из тех же моделей. По мнению Magento о мире, наличие блока, основанного на контроллере, который делает определенную вещь, является тесной связью, и его следует избегать.

Работа вашего контроллера заключается в том, чтобы делать определенные вещи с Моделями, а затем сообщать системе, что время рендеринга макета. Вот и все. Ваша задача «Разметка / блокировка» - отображать HTML-страницу определенным образом в зависимости от состояния моделей системы.

Итак, если бы я хотел эмулировать традиционное поведение PHP MVC, я бы

  1. Создать простой класс Model, наследуемый от Varien_Object

  2. В контроллере создайте экземпляр этого объекта с помощью Mage::getSingleton('foo/bar')

  3. Установите значения в модели с помощью магического геттера / сеттера (вы получаете их в объектах, которые наследуются от Varien_Object) или setData и т. Д.

  4. В блоках снова создайте экземпляр модели с помощью Mage::getSingleton('foo/bar') и прочитайте значения обратно.

Когда вы создаете экземпляр модели с помощью Mage::getSingleton(...) Magento будет создавать экземпляр объекта в виде одиночного . Итак, если вы повторно создаете экземпляр объекта (снова с помощью Mage::getSingleton('foo/bar')), вы получаете тот же объект.

35 голосов
/ 24 октября 2010

Если вы используете блоки, которые наследуют Mage_Core_Block_Template (т. Е. Используют шаблон для отображения), вы можете назначать данные с помощью метода assign (), как только блоки были инстанцируется loadLayout()

$this->loadLayout(array('default', 'myModule_default'));

$this->getLayout()->getBlock('your.block.name.in.the.layout')->assign('data', $data);

Затем в шаблоне .phtml вы можете просто использовать

<?php echo $data ?>

Это не очень часто используется в magento, но, поскольку он реализован как публичные методы и поэтому объявлен как стабильный, я считаю, что это нормально. Это также является причиной того, что в соглашении переменные, объявленные в шаблоне, начинаются с подчеркивания (например, $_product = $this->getProduct()), чтобы их можно было отличить от назначенных переменных.

4 голосов
/ 24 октября 2010

Что мне помогло в этом, так это установить переменную в контроллере, выполнив:

Mage::register('variable', 'value');

И затем в представлении вы получите значение, используя следующий код:

$variable = $this->getVariable();
2 голосов
/ 24 октября 2010

Вы на правильном пути, используя подход Mage::registry().Другой вариант - использовать автоматические геттеры и сеттеры, например, $this->setRandomVariableName($data) в контроллере, а затем в блоке использовать $this->getRandomVariableName().Я не исследовал, оказываются ли они в одном месте в стеке (я предполагаю, что в сеансе они зависят от запроса), но они достигают той же цели в коде.

Использование методов получения и установки может иногда приводить в замешательство, поскольку может показаться, что вы получаете доступ к данным через ORM, а не «временную» переменную сеанса, поэтому вы можете принять решение о согласованности стиля кодирования для использования Mage::registry для этих типов переменных.Твой выбор действительно.

0 голосов
/ 05 августа 2011

@ Drew Имея некоторый опыт работы с JavaServer Faces и довольно новый в PHP / Magento, я хотел бы заявить, что

"не разделяющая ничего" архитектура PHP ",

см. PHP не Java: документ управления сессиями ", приводит к тому, что все объекты (и даже классы) в PHP имеют область действия" запрос ".

Если я получил точку Алана, то он советуетиспользуйте

  • объект модели с сохранением состояния, который имеет некоторые данные в своих атрибутах, которые не обязательно хранятся в базе данных
  • , и шаблон синглтона, с использованием Mage :: getSingleton, чтобы сделать эту модель с состоянием, которая создается в контроллере, доступной для блока и, следовательно, в фактическом шаблоне, который отображает выходные данные.

И так как такой инструмент, как MTool сокращает время на создание новой модели, это действительно имеет смысл.

0 голосов
/ 12 июля 2011

Вы можете использовать пару setData / getData для некоторых значений. Я использовал setData в контроллере и getData в блоке.

...