在Magento中,块如何从模型中获取数据?

时间:2012-03-19 01:03:53

标签: magento

有人可以解释一下吗?

让我告诉你我所知道的。如果前三点好,请解释4点。

  1. 请求来到控制器。
  2. 在Controller Action中,我们启动模型。
  3. 模型收集或生成连接数据库等所需的所有信息。
  4. 之后会发生什么?

    1. 模型如何将数据传输到Blocks,或者块从模型中获取数据?

    2. 模板获取准备好的数据并显示在屏幕上

      • 此外,请求是否再次返回控制器?
    3. 请解释一下。我在几个地方感到困惑。

2 个答案:

答案 0 :(得分:39)

没有任何东西将数据传输到块。控制器操作完成其模型交互后,它负责

  1. 加载布局对象(间接加载和创建块对象)

  2. 告诉布局对象呈现页面。

  3. 大多数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)

  1. 通过前端控制器和路由器正确
  2. 不太好。 Magento的ViewModel实现部分是通过让视图(Blocks)实例化自己的模型来实现的。
  3. 是的,通过资源模型。
  4. 当通过动作控制器中的典型$this->loadLayout()->renderLayout()流渲染块时,如果它们使用模板,那么这些模板在渲染时为include() d。

    renderLayout()调用之后,执行仍然在我们调度到的控制器操作的范围内,因此您可以通过获取请求对象来访问呈现的响应。

    关键情节点:

    1. index.php调用Mage::run()
    2. Mage::run来电Mage_Core_Model_App::run()
    3. App::run()调用Mage_Core_Controller_Varien_Front,首先是收集和设置路由器的init()方法,然后dispatch()执行以下操作:

      一个。数据库URL重写

      湾配置重写(不建议使用)

      ℃。通过路由器匹配正确的控制器操作。执行从Front Controller跳转到动作控制器。使用布局或手动调用块然后将执行传递给块类和模型和模板,然后我们(通常)返回到控制器操作。

      d。发送响应对象(假设它已被动作控制器更改)。

    4. 如果你看Mage_Core_Controller_Varien_Front::dispatch(); you'll see the call to $ this-> getResponse() - > sendResponse();`它将刷新输出,前面有一个事件(controller_front_send_response_before),它可以用作一个钩子来添加或操纵任何与响应相关的内容。