将数据从控制器传递到模板
从“模板和布局渲染”课程中,我们学习了如何创建新模板并借助布局在自定义页面上渲染它。您已经注意到,该模板为HTML标记提供了静态文本。
<h1>My First Template</h1>
<p>With Layout support</p>
这对于静态网站来说可能已经足够了,但是对于Magento 2网站来说就不够了。在本课中,我们将学习如何从PHP端传递数据,特别是从动作控制器传递到模板。
在本课结束时,您将了解如何在页面上呈现动态内容的一种方法
课程概述
在本课程中,我们将学习以下内容:
- 如何将数据从控制器类传递到模板?
- 如何从控制器访问块类?
- 如何将数据分配给块类?
- 如何在模板中呈现动态数据?
开始之前
您需要从上一课下载源代码才能继续上课。
Controller Logic :控制器逻辑
让我们仔细看一下View Controller类的execute()方法。
Controller / Page / View.php文件:
public function execute()
{
return $this->resultFactory->create(ResultFactory::TYPE_PAGE);
}
正如您所看到的:
- resultFactory是用于创建一个Magento\Framework\View\Result\Page 类的新实例。
- Page 类包含逻辑,该逻辑用于呈现页面上的所有块和模板。
- Page类创建的实例包括从MageMastery_FirstLayoutmodule到example.phtmltemplate的路径。
- 一旦execute()方法返回PageObject,它将触发Page :: render()方法,并将内容呈现在页面上 .
但是,如果我们要将内容从Controller类传递到example.phtmltemplate中,则应该修改execute()方法的逻辑。
- 首先,让我们将create()方法的结果分配给$page 变量。
public function execute()
{
/** @var Page $page */
$page = $this->resultFactory->create(ResultFactory::TYPE_PAGE);
return $page;
}
- 现在,我们可以访问页面中添加的任何Block类,以进行进一步渲染。 Page类对Layout 类有依赖关系,可通过调用getBlock()方法将其用于检索块的实例。 getBlock(string $ name)方法接受$ name参数。
- 在上一课中,我们讨论了添加到magemastery_firstlayout_page_view.xml layout布局)文件中的Block声明的名称是magemastery.first.layout.example。 我们可以通过调用getBlock()方法并传递块名称来检索块的实例。
<block class="Magento\Framework\View\Element\Template"
name="magemastery.first.layout.example"
template="MageMastery_FirstLayout::example.phtml" />
$block 变量是引用一个Template类的实例。
$block = $page->getLayout()->getBlock('magemastery.first.layout.example');
template类允许我们设置其他数据。 为此,必须使用setData()方法。 还有其他方法可以将数据设置为Templateobject,但是在本课程中,我们将仅使用setData()方法。 Template :: setData(字符串$ name,混合$ value = null)方法接受两个参数。 第一个参数是必须为其设置值的键的名称。 此外,必须使用键来访问分配的值。
让我们为名为custom_parameter的键分配一个值.
$block->setData('custom_parameter', 'Data from the Controller');
结果,该块实例分配了新数据,并且可以通过getData()方法进行访问。
$data = $block->getData();
print_r($data);
/* Retult
Array (
[type] => Magento\Framework\View\Element\Template
[custom_parameter] => Data from the Controller
)
*/
另外,我们可以将键的名称传递给getData(string $ key = null,int $ index = null)方法。
customParameter = $block->getData('custom_parameter');
echo $customParameter;
// Result: Data from the Controller
修改后的execute()方法的结果:
execute()方法创建Pageclass的实例,从已声明的具有magemastery.first.layout.exampleblock名称的块池中返回Template的实例。 然后,将自定义值分配给块。 最后,Page对象从execute()方法返回以进行渲染。
The app/code/MageMastery/FirstLayout/Controller/Page/View.php file:
<?php
declare(strict_types=1);
namespace MageMastery\FirstLayout\Controller\Page;
use Magento\Framework\App\Action\Action;
use Magento\Framework\Controller\ResultFactory;
use Magento\Framework\View\Element\Template;
use Magento\Framework\View\Result\Page;
class View extends Action
{
public function execute()
{
/** @var Page $page */
$page = $this->resultFactory->create(ResultFactory::TYPE_PAGE);
/** @var Template $block */
$block = $page->getLayout()->getBlock('magemastery.first.layout.example');
$block->setData('custom_parameter', 'Data from the Controller');
return $page;
}
}
Template Logic
Magento \ Framework \ View \ Element \ Template类渲染的每个PHTML模板都可以访问模板内部的$block 变量。 $ block 变量是扩展Template类的当前Template类或任何子类的实例。
为了访问example.phtml内的’custom_parameter’,我们必须使用Template :: getData()方法。
<p><?= $block->getData('custom_parameter'); ?></p>
添加带有类名的文档块也是很实际的,因此在我的案例中,IDE(PHPStorm)将突出显示所有公共方法。 最后的example.phtml 模板如下:
<?php
use Magento\Framework\View\Element\Template;
/** @var Template $block */
?>
<h1>My First Template</h1>
<p>With Layout support</p>
<p><?= $block->getData('custom_parameter'); ?></p>
因此,页面应呈现自定义参数。

重要须知
即使您可以在PHTML模板中使用PHP,模板中也不应包含任何业务或计算逻辑。 所有业务逻辑都应位于代表此类业务逻辑的所谓服务层或PHP类中。 在接下来的课程中,我们将更多地讨论服务层。 PHTML模板应尽可能简单和小巧,并且仅在内部包含数据和简单的PHP逻辑(例如循环和条件)。
其他传递动态数据的方法
这不是将数据从PHP类传递到PHTML模板的唯一方法。 这只是构建自定义Magento 2功能时应注意的方法之一。 将数据传递到PHTML模板的首选方法是使用View Model类。 View Model类及其功能是Magento 2 for Beginners课程的下一课。