真的快速而简单的问题,但我找不到合适的答案 - 在Magento中将数据从控制器传递到块的最佳方法是什么。
如果它有所不同,我按如下方式加载布局:
$this->loadLayout(array('default', 'myModule_default'));
$this->_initLayoutMessages('customer/session')
->_initLayoutMessages('catalog/session')
->renderLayout();
我应该补充一点,我一直在使用注册表如下:
在控制器中:
Mage::register('data', $data);
在街区:
$data = Mage::registry('data');
不确定这是否是最好的方法。
答案 0 :(得分:83)
你没有。
在Magento的MVC方法中,控制器不负责为视图设置变量(在Magento的情况下,视图是布局和块)。控制器在模型上设置值,然后从这些模型中读取块。在Magento对世界的看法中,让Block依靠控制器执行特定的操作是紧密耦合,应该避免。
你的控制器的工作是对模特做某些事情,然后告诉系统它的布局渲染时间。而已。根据系统模型的状态,以某种方式显示HTML页面是您的布局/块工作。
所以,如果我想模仿传统的PHP MVC行为,我会
创建一个继承自Varien_Object
在控制器中,使用Mage::getSingleton('foo/bar')
使用魔术吸气剂/设定器在模型上设置值(您可以在继承自Varien_Object
)或setData
等的对象中获取这些值。
在Blocks中,使用Mage::getSingleton('foo/bar')
再次实例化模型,并重新读取值。
使用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,那么他建议使用
由于像MTool这样的工具减少了创建新模型的时间,因此这似乎很有意义。