有人可以解释一下吗?
让我告诉你我所知道的。如果前三点好,请解释4点。
之后会发生什么?
模型如何将数据传输到Blocks,或者块从模型中获取数据?
模板获取准备好的数据并显示在屏幕上
请解释一下。我在几个地方感到困惑。
答案 0 :(得分:39)
没有任何东西将数据传输到块。控制器操作完成其模型交互后,它负责
加载布局对象(间接加载和创建块对象)
告诉布局对象呈现页面。
大多数Magento控制器操作在控制器操作结束时执行两次调用。
$this->loadLayout();
$this->renderLayout();
在Magento中,没有任何内容可以在视图上设置数据。相反,视图(即块对象)向系统询问数据。您可以在Mage_Tag_Block_Customer_View
块类中看到此示例。
#File: app/code/core/Mage/Tag/Block/Customer/View.php
...
public function getTagInfo()
{
if (is_null($this->_tagInfo)) {
$this->_tagInfo = Mage::getModel('tag/tag')
->load($this->getTagId());
}
return $this->_tagInfo;
}
...
此处,此块的getTagInfo
方法直接向模型询问其信息。这样,前端模板开发人员可以访问
$this->getTagInfo();
方法。我在good authority上也知道,块_prepareLayout
方法是将大部分(如果不是全部)数据提取到块中的完美位置。
您将看到的第二种模式是Magento注册表模式。这是一个Magento系统,可以让您设置系统范围(但不是PHP)的全局变量。
Mage::register('foo', 'some value');
echo Mage::registry('foo');
有时,Magento开发人员将使用注册表在控制器操作中设置变量,然后在块中取回。例如,在管理控制台的发票控制器中。
#File: app/code/core/Mage/Adminhtml/controllers/Sales/Order/InvoiceController.php
protected function _initInvoice()
{
...
$invoice = Mage::register('current_invoice', $invoice);
return $invoice;
}
然后Block会在稍后引用它。
#File: app/code/core/Mage/Sales/Block/Order/Print/Invoice.php
public function getInvoice()
{
return Mage::registry('current_invoice');
}
我并没有对注册表模式感到愤怒,但核心团队使用它,所以它可能是犹太人。
最后,如果您希望模拟大多数PHP MVC框架中使用的“哑视图”模式,请尝试这样的事情
$this->loadLayout();
$block = $this->getLayout()->getBlock('block_name');
$block->setSomeData('My Data');
$block->setData('alternate_syntax', 'Some other data');
$this->renderLayout();
然后在块和/或模板文件中。
echo $this->getSomeData();
echo $this->getData('some_data');
echo $this->getAlternateSyntax();
echo $this->getData('alternate_syntax');
调用loadLayout
后,Magento将创建所有块对象。您上面所做的是获取对特定块对象的引用,然后设置其数据。
Per Vinai的评论如下,还有一个块的assign
方法需要考虑。
与setData
类似,在调用loadLayout
(或从块的_prepareLayout
)方法调用后,您可以执行类似
$this->loadLayout();
$block = $this->getLayout()->getBlock('block_name');
$block->assign('my_view_var','Something for the view');
$this->renderLayout();
然后在您的块的phtml
文件中,您将能够输出该视图变量
echo $my_view_var;
答案 1 :(得分:3)
当通过动作控制器中的典型$this->loadLayout()->renderLayout()
流渲染块时,如果它们使用模板,那么这些模板在渲染时为include()
d。
在renderLayout()
调用之后,执行仍然在我们调度到的控制器操作的范围内,因此您可以通过获取请求对象来访问呈现的响应。
关键情节点:
Mage::run()
Mage::run
来电Mage_Core_Model_App::run()
App::run()
调用Mage_Core_Controller_Varien_Front
,首先是收集和设置路由器的init()
方法,然后dispatch()
执行以下操作:
一个。数据库URL重写
湾配置重写(不建议使用)
℃。通过路由器匹配正确的控制器操作。执行从Front Controller跳转到动作控制器。使用布局或手动调用块然后将执行传递给块类和模型和模板,然后我们(通常)返回到控制器操作。
d。发送响应对象(假设它已被动作控制器更改)。
如果你看Mage_Core_Controller_Varien_Front::dispatch(); you'll see the call to
$ this-> getResponse() - > sendResponse();`它将刷新输出,前面有一个事件(controller_front_send_response_before),它可以用作一个钩子来添加或操纵任何与响应相关的内容。