2010-10-23 5 views
46

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

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

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

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

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

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

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

В блоке:

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

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

ответ

79

У вас нет.

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

Задача вашего контроллера - делать определенные вещи для моделей, а затем указывать системе время рендеринга макета. Вот и все. Это ваша задача Layout/Blocks для отображения HTML-страницы определенным образом в зависимости от состояния моделей системы.

Так что, если я хотел подражать традиционные модели поведения PHP MVC Я бы

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

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

  3. Задайте значения в Модели с помощью волшебных приемников/сеттеров (вы получите их в объектах, которые наследуются от Varien_Object), или setData, e дц.

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

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

+1

Спасибо, это очищает мое замешательство после появления стандартных приложений Zend MVC. –

+2

@Neil Да, есть много путаницы там. Magento использует некоторые компоненты рамки zend, но сам по себе является каркасом. –

+0

+1 к этому ответу. Однако, я думаю, ответ Винаи тоже хорош, особенно когда вы на начальных этапах и вы должны убедиться, что ваши данные загружаются и передаются должным образом. Лично я бы рекомендовал использовать «ультраразвязанный» метод на более позднем этапе, чтобы избежать слишком большого количества тест сразу. – Diego

2

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

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

+0

Я пробовал это раньше, предполагая, что будут магические геттеры и сеттеры - я всегда получаю неопределенную ошибку метода. –

+0

Хм, возможно, вам нужна инстанцированная модель для выполнения автоматической магии get/set. Это может не работать над $ this в контексте контроллера. Если у вашего контроллера уже есть объект, созданный 'Mage :: getModel ('module/model'), тогда вы сможете его использовать. Вероятно, это также дает переменной больше контекста, что хорошо ... –

+2

Magic getPropName и setPropName работают только с объектами, которые наследуются от Varien_Object. –

4

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

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

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

$variable = $this->getVariable(); 
34

Если вы используете блоки, которые наследуют 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()), поэтому их можно отличить от назначенных переменных.

+1

Заинтересовано, почему использование 'assign()' лучше, чем волшебный сеттер, например. 'УстановитьДанные()'? –

+0

Нет, я бы сказал, что они эквивалентны. – Vinai

+0

@JonathanDay Я избегаю магических методов, таких как чума, потому что современные IDE, которые выполняют статический анализ, блокируют «магический» код, который не дополняется аннотациями (большая часть Magento). Intellisense тоже плюс. –

0

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

0

@Drew С некоторыми фона в JavaServer Faces и довольно нового в PHP/Magento Я хотел бы заявить, что

«„доля ничего“архитектуры PHP»,

см PHP is not Java: Session Management Whitepaper", приводит к факт, что все объекты (и даже классы) в PHP имеют «запрос».

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

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

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

Смежные вопросы