BetterBlocksMagento2PHPViewModels(PHP视图模型让模块开发更独立)

编程

Blocks的问题
虽然Blocks可以很好的完成他们的工作,他们也有一些缺点。
所有的Blocks都使用构造注入,所以当一个Block需要额外的依赖的时候,它必须把依赖上下文变量传入parent::__construct()方法。

自然,许多开发人员然后通过受保护的getter或受保护的字段访问父项依赖项。这些定制逻辑和平台代码的交织导致代码更加复杂。 与简单的没有继承关系的类相比,代码变得难以理解和维护。

另外,当使用测试来驱动开发时,虽然依赖关系跟业务逻辑没有任何关系,但是因为必须处理父类之间的关系,使过程变得十分繁琐。 这是开发人员踏上TDD旅程的又一个障碍,并助长了难以进行测试的神话。

PHP视图模型 在写这编文章的时候我发现了以下模版block类上面的PHPDoc注释。

/** * Avoid extending this class. *
* If you need custom presentation logic in your blocks, use this class as block, and declare
* custom view models in block arguments in layout handle file.

* * Example: * * * MyModuleViewModelCustom *
* **/

此注释已添加到2.2版本中,并准确描述了Anton所指的内容。
更好的是,自Magento 2.2.1版本,我们甚至不用指定的class参数,因为 class="MagentoFrameworkViewElementTemplate" 是默认值。
现在我大多使用以下方式来声明我的Blocks, ExampleViewModelBlockExample
<referenceContainer name="columns.top">
    <block name="view-model-example" template="Example_ViewModel::example.phtml">
        <arguments>
            <argument name="view_model" xsi:type="object">ExampleViewModelBlockExample</argument>
        </arguments>
    </block>
</referenceContainer>
模版是这样开始的: 
<?php declare(strict_types=1);

/** @var ExampleViewModelBlockExample $viewModel */
$viewModel = $block->getData("view_model");

?>

<?php $viewModel->getSomeThing() ?>
这个视图模块必须实现标记接口,否则我们会遇到一个异常:
(UnexpectedValueException): Instance of MagentoFrameworkViewElementBlockArgumentInterface is expected, got ExampleViewModelBlockExample instead.

这个是异常中所指的ArgumentInterface
/** * Block argument interface.
* All objects that are injected to block arguments should implement this interface.
*/

interface ArgumentInterface { }

此限制是安全预防措施,由于布局可以在多个文件内配置--包括后台由商户添加的布局--此限制被用来限制由布局声明实例化Blocks的个数。
实际上,必须实现此接口并不是真正的麻烦。 我喜欢使用几乎解耦的视图模型,而不是从AbstractBlock扩展的块。

<

?

php

declare

(

strict_types

=

1

)

;

 

namespace

Example

ViewModel

Block

;

 

use

Magento

Framework

View

Element

Block

ArgumentInterface

;

 

class

Example

implements

ArgumentInterface

{

    

public

function

getSomeThing

(

)

    

{

        

// ...

    

}

}

构造函数不需要调用 parent::__construct(),任何依赖关系都显而易见
在某些情况下,仍然需要使用自定义块。 例如,根据条件判断对模版进行渲染。 但是在大多数情况下,视图模型已经足够了。

视图模型的好处
简而言之,使用视图模型代替块可以更好地分离自定义代码和平台代码,这导致代码具有以下属性:

更容易理解
更易于维护
更可重用
更安全的升级
更容易测试

以上是 BetterBlocksMagento2PHPViewModels(PHP视图模型让模块开发更独立) 的全部内容, 来源链接: utcz.com/z/513157.html

回到顶部