Magento – 在控制器和块之间传递数据

真的很快又简单的问题,但我找不到一个体面的答案 – 什么是从控制器传递数据到Magento块的最佳方式。

Incase它有所不同,我加载布局如下:

$this->loadLayout(array('default', 'myModule_default')); $this->_initLayoutMessages('customer/session') ->_initLayoutMessages('catalog/session') ->renderLayout(); 

我应该补充一点,我一直在使用registry如下:

在控制器中:

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

在块中:

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

不知道这是否是最好的办法。

你没有。

在Magento的MVC方法中,为视图设置variables不是控制器的责任(在Magento的情况下,视图是布局和块)。 控制器在模型上设置值,然后从这些模型中读取块。 在Magento的世界观中,依靠控制器做一个特定的事情是一个块紧耦合,应该避免。

你的控制器的工作是对模型做某些事情,然后告诉系统它的布局渲染时间。 而已。 这是您的布局/块作业根据系统模型的状态以某种方式显示HTML页面。

所以,如果我想模仿传统的PHP MVC行为,我会的

  1. 创build一个从Varien_Objectinheritance的简单Model类

  2. 在控制器中,使用Mage::getSingleton('foo/bar')实例化对象

  3. 在模型上使用神奇的getter / setter(你从Varien_Objectinheritance的对象中获得这些Varien_Object )或者setData等等来设置值。

  4. 在块中,用Mage::getSingleton('foo/bar')再次实例化模型并读取值。

当你使用Mage::getSingleton(...)实例化一个模型时,Magento会将这个对象实例化为一个单例 。 所以,如果你重新实例化一个对象(再次用Mage::getSingleton('foo/bar') ),你会得到相同的对象。

如果您使用的是inheritanceMage_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() )声明的variables的原因,因此可以将它们与分配的variables区分开来。

在我的工作是在控制器中设置variables做:

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

然后在视图中,您将使用以下代码检索值:

 $variable = $this->getVariable(); 

你正在使用Mage::registry()方法正确的轨道。 另一个select是在控制器中使用自动获取器和设置器,例如$this->setRandomVariableName($data) ,然后在块中使用$this->getRandomVariableName() 。 我还没有调查他们是否在堆栈中的相同位置(我假设在会话中,因为它们是请求特定的),但是他们在代码中实现相同的目标。

使用getters和setter可能会偶尔会引起混淆,因为它可能看起来像通过ORM访问数据而不是“临时”会话variables,所以您可能会做出一个编码风格的一致性决定,使用Mage::registry来处理这些types的variables。 你的select真的。

你可以使用setData / getData对来获得一些值。 我在控制器中使用setData,并在块中使用getData。

@Drew在JavaServer Faces中有一些背景,而在PHP / Magento中更新一些,我想说明一下

“”什么也没分享“PHP体系结构”,

请参阅PHP不是Java:会话pipe理白皮书“ ,导致PHP中的所有对象(甚至是类)都具有范围”请求“的事实。

如果我得到阿兰斯点,那么他build议使用

  • 一个“有状态的”模型对象,它的属性中有一些数据不一定存储在数据库中
  • 而单体模式通过使用Mage :: getSingleton来创build这个有状态的模型,这个模型在控制器中被实例化,可以访问块,因此在实际的模板中可以呈现输出。

而且由于像MTool这样的工具缩短了创build新模型的时间,所以这似乎是有道理的。