Qu'est-ce qu'un view model ?
Les view models sont des classes qui permettent d'éviter d'avoir à récupérer toute la DI du parent d'un block lorsque l'on veut ajouter une dépendance à une classe.
Imagineons par exemple que nous ayons un block qui étende Magento\Catalog\Block\Product\ProductList\Toolbar, si nous vous ajouter une dépendance à notre block, nous allons devoir reprendre tous les paramètres de la méthode __construct :
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
\Magento\Catalog\Model\Session $catalogSession,
\Magento\Catalog\Model\Config $catalogConfig,
ToolbarModel $toolbarModel,
\Magento\Framework\Url\EncoderInterface $urlEncoder,
ProductList $productListHelper,
\Magento\Framework\Data\Helper\PostHelper $postDataHelper,
array $data = [],
ToolbarMemorizer $toolbarMemorizer = null,
Context $httpContext = null,
FormKey $formKey = null
) {
$this->_catalogSession = $catalogSession;
$this->_catalogConfig = $catalogConfig;
$this->_toolbarModel = $toolbarModel;
$this->urlEncoder = $urlEncoder;
$this->_productListHelper = $productListHelper;
$this->_postDataHelper = $postDataHelper;
$this->toolbarMemorizer = $toolbarMemorizer ?: ObjectManager::getInstance()->get(
ToolbarMemorizer::class
);
$this->httpContext = $httpContext ?: ObjectManager::getInstance()->get(
Context::class
);
$this->formKey = $formKey ?: ObjectManager::getInstance()->get(
FormKey::class
);
parent::__construct($context, $data);
}
Cela va compliquer notre block "pour rien". Nous pouvons donc ici ajouter un view model, qui sera une classe à part :
<referenceBlock name="mon.block">
<arguments>
<argument name="view_model" xsi:type="object">Vendor\Module\ViewModel\Monviewmodel</argument>
</arguments>
</referenceBlock>
La classe du view model sera disponible via $block->getViewModel(). Nous pourrons donc ajouter une méthode à notre view model et faire en sorte qu'un template existant l'appelle sans avoir à surcharger le block parent.
Par exemple dans le template, nous pourrions faire :
<?php echo $block->getViewModel()->getHelloText() ?>
Et dans le view model :
<?php
namespace Vendor\Module\ViewModel;
class Monviewmodel implements \Magento\Framework\View\Element\Block\ArgumentInterface
{
public function getHelloText()
{
// ...
}
}