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

时间:2010-10-23 21:34:29

标签: php variables magento model session-variables

真的快速而简单的问题,但我找不到合适的答案 - 在Magento中将数据从控制器传递到块的最佳方法是什么。

如果它有所不同,我按如下方式加载布局:

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

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

我应该补充一点,我一直在使用注册表如下:

在控制器中:

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

在街区:

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

不确定这是否是最好的方法。

6 个答案:

答案 0 :(得分:83)

你没有。

在Magento的MVC方法中,控制器不负责为视图设置变量(在Magento的情况下,视图是布局和块)。控制器在模型上设置值,然后从这些模型中读取块。在Magento对世界的看法中,让Block依靠控制器执行特定的操作是紧密耦合,应该避免。

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

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

  1. 创建一个继承自Varien_Object

  2. 的简单Model类
  3. 在控制器中,使用Mage::getSingleton('foo/bar')

  4. 实例化该对象
  5. 使用魔术吸气剂/设定器在模型上设置值(您可以在继承自Varien_Object)或setData等的对象中获取这些值。

  6. 在Blocks中,使用Mage::getSingleton('foo/bar')再次实例化模型,并重新读取值。

  7. 使用Mage::getSingleton(...)实例化模型时,Magento会将对象实例化为单例。因此,如果您重新实例化一个对象(再次使用Mage::getSingleton('foo/bar')),您将获得相同的对象。

答案 1 :(得分:35)

如果您使用的是继承 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())的原因,因此可以将它们与指定的变量区分开来。

答案 2 :(得分:4)

对我来说有用的是通过执行以下操作在控制器中设置变量:

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

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

$variable = $this->getVariable();

答案 3 :(得分:2)

您使用Mage::registry()方法走在正确的轨道上。另一种选择是使用自动吸气剂和设定器,例如控制器中的$this->setRandomVariableName($data)然后在块中使用$this->getRandomVariableName()。我没有调查它们是否最终位于堆栈中的相同位置(我在会话中假设它们是特定于请求的),但它们在代码中实现了相同的目标。

使用getter和setter有时会让人感到困惑,因为它看起来像是通过ORM访问数据而不是“临时”会话变量,所以你可能会做出编码式一致性决定来使用{{1}对于那些类型的变量。你的选择真的。

答案 4 :(得分:0)

您可以将setData / getData对用于某些值。 我在控制器中使用了setData,在块中使用了getData。

答案 5 :(得分:0)

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

“'没有共享'PHP架构”,

参见PHP is not Java: Session Management Whitepaper",导致PHP中的所有对象(甚至类)都具有范围“请求”。

如果我得到了Alans,那么他建议使用

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

由于像MTool这样的工具减少了创建新模型的时间,因此这似乎很有意义。