Magento 2:将变量从控制器操作传递到“视图”


12

在Magento 1中,如果要将数据从Controller动作传递到“视图”(即,布局中的块,则可以)

  1. 通过以下方式将值/对象添加到全局注册表中 Mage::register

  2. 运行后直接获取块对象并在获取的块对象上设置数据属性 loadLayout

  3. 调用phtml文件中块对象的方法,并使块对象使用模型/数据库层读取以前保存在控制器动作中的数据

在Magento 2中,仍然可以使用块对象方法从数据库中读取数据,这适用于某些类型的操作。然而,

  1. Magento 2中不再有全局注册表(或存在?)

  2. 现在,布局系统可以通过工厂创建页面对象来工作,并且您无法像在Magento 1中一样获取块引用

在Magento 2中,是否可以将数据从控制器动作直接传递到视图?还是对于Magento勇敢的全新Design Pattern™世界而言,这是否太直接了?如果这是直接模式,那么如果我们要在模板中显示一些计算出的信息,但又不想将该信息存储到有状态系统中(即我们不想将其保存到数据库)

我可以想出几种不同的方法来自己破解这些东西-但我对Magento 2 希望您如何做感兴趣。

注意:我意识到可以使用类似这样的方法在控制器动作中获取块实例

$resultPage = $this->resultPageFactory->create();    
$block = $resultPage->getLayout()->getBlock('catalog.wysiwyg.js');        

var_dump(spl_object_hash($block));

Magento 2核心代码经常这样做。但是-在控制器对象中获取的块对象似乎与phtml通过$this或在模板中可用的对象不同$block(前者($this似乎是实际呈现模板的对象,而后者($block)似乎是实际呈现模板的对象) Magento块类型的实例)。

#File: path/to/template.phtml
var_dump(spl_object_hash($block));
var_dump(spl_object_hash($this));

我之所以说“似乎是”,是因为如果我在controller action方法中设置数据,则该数据在phtml模板中不可用-如果我比较spl_object_hash上面的结果,则会得到三个不同的哈希值。但是,对于这一切我还是很陌生,因此上面的内容可能是我犯的其他错误-因此,如果您能够在块上设置数据并将其提取到模板中,那么我很想听听!

Answers:


17

关于#1,注册表仍然存在,与您从Magento 1所知非常相似。它只是移动了。看到:\Magento\Framework\Registry

通过依赖项注入将其添加到构造函数中,然后可以使用您熟悉的$registry->register($key, $value)$registry->registry($key)方法存储/访问数据。

如果您还没有的话,我建议您在\ Magento \ Framework命名空间中戳一下。之前从Mage或App可以访问的许多内容仍然存在,只是分开了。

就最佳实践而言,我无法回答,但我希望答案将是使控制器中保持尽可能多的逻辑。看核心可能是您最好的选择。例如,请参见客户地址编辑页面:基本控制器扩展块-包括提取地址ID和加载(如有必要)。他们直接在块中处理;他们不会在控制器中执行此操作,然后将其传递出去。


2
诀窍当然是知道内核要看哪些部分,而忽略什么:)感谢指针,+1是有用的信息!
艾伦·风暴

1
+1为最后一段。如果需要共享一些计算值,则将计算行为放在单独的对象中,并从需要该值的块中调用它。不建议使用注册表,因为它是全局可变状态,您永远不确定从那里会得到什么。不建议直接从动作中寻址块,因为您不确定页面上是否存在块(布局会杀死它)
Anton Kril

@AntonKril页面渲染器助手如何?CMS页面帮助程序,产品视图帮助程序,是用来将呈现与HTTP请求分开的吗?
伊万·谢普尔尼

5

你应该传递变量从控制器操作来查看。使用block将变量传递给View(模板引擎)。


为什么?您如何从块传递get / post参数到视图?大多数逻辑不是将它们从控制器传递给视图吗?
LucScu

在块中使用请求对象。如果通过注册表阻止从控制器获取数据,则不能将其与其他控制器一起使用。这就是所谓的时空耦合及其不良做法
康提

我使用$ block-> assign()从控制器到块传递请求的参数。这也是不好的做法吗?
LucScu

不建议直接从动作中寻址块,因为您不确定页面上是否存在块。
康迪

就我而言,我确定,因为这是一个自定义方案,其中控制器,布局和块仅由我的代码控制,所以我认为逻辑传递请求的参数从控制器到块。感谢您的回复!
LucScu
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.