Hi,
I was pointed to a comment in the new Magento 2.2 source that explains how to use an XML layout statement inserting the generic Magento Block-class Magento\Backend\Block\Template into the layout and using its arguments to inject your own "View Model" into that generic block as follows:
<argument name="viewModel" xsi:type="object">My\Module\ViewModel\Custom</argument>
I can see the benefit of that: You don't need to extend the parent-class and instead can inject all of your dependencies in a clean My\Module\ViewModel\Custom class. It is almost as if it is introduced as a new feature, while actually, it is not - it's possible with any Magento 2 version.
The comment does not say how the View Model should be used. From basic M2 knowledge, I can deduct that the variable viewModel is added to the blocks $data array and therefore is able to be called from within the PHTML template using a call like $viewModel = $block->getViewModel().
Or alternatively, I could add $this->assign('viewModel', $this->getData('viewModel')); somewhere in a Block class anyway and use that variable in my PHTML template like $viewModel. I even could add a Plugin (interceptor) to do this automatically.
My question is: What would be the general advice here? Is viewModel really a suggested name, or could it be anything? Of course, it can. But it might be a good idea to introduce a new pattern called ViewModels and labeling them in the same way. Is there any vision that we should consider?
Solved! Go to Solution.
1. Suggested name for case when you have a single view model in your block is $viewModel
2. Because there might be multiple view models used (for better separation of concerns), the name is not enforced.
3. The good practice is to have a "ViewModel" namespace in your module folder. That is also not enforced.
4. The easiest use of the view model in template is
$block->getViewModel();
1. Suggested name for case when you have a single view model in your block is $viewModel
2. Because there might be multiple view models used (for better separation of concerns), the name is not enforced.
3. The good practice is to have a "ViewModel" namespace in your module folder. That is also not enforced.
4. The easiest use of the view model in template is
$block->getViewModel();
Thanks, Anton. So we call it ViewModels. I've been explaining this to my first students already and they are delighted.
What if we want to add our custom viewModel to a core block and therefore be able to use in core phtml replaced by a custom phtml?
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceBlock name="name.of.the.core.block" template="Vendor_ModuleName::path/to/template.phtml"> <arguments> <argument name="viewModel" xsi:type="object">Vendor\ModuleName\ViewModel\Class</argument> </arguments> </referenceBlock> </body> </page>
It is possible and it works as expected!
The reason why the previous example was not working for me was because I was not implementing the right interface in my viewModel class.
All viewModels need to to implement ArgumentInterface.
namespace Vendor\CustomModule\ViewModel; class Class implements \Magento\Framework\View\Element\Block\ArgumentInterface{ public function __construct() { } }
It seems like all viewModel need to implement
\Magento\Framework\View\Element\Block\ArgumentInterface
The most important part of using ViewModel is it simplifies the load time as we only implements Magento\Framework\View\Element\Block\ArgumentInterface. If we use a custom block instead of ViewModel, we should extend the core block Magento\Framework\View\Element\Template which includes so many handy things like some extra blocks, loggers etc. And we can easily access the ViewModel by $block->getViewModel().
Hi there,
The use of View Models in Magento 2, as described in the comment you mentioned, provides a clean and efficient way to inject dependencies into generic blocks without the need for extending parent classes. While the comment doesn't explicitly detail how to use the View Model, your deduction is correct.
Here's some insight into your questions:
1. **Usage of View Model**: Typically, when you inject a View Model into a block using XML layout, the View Model instance becomes available within the block's `$data` array. As you mentioned, you can retrieve it in your PHTML template using `$viewModel = $block->getViewModel()`. Alternatively, you could also assign it directly in the block class using `$this->assign('viewModel', $this->getData('viewModel'))` and then use `$viewModel` in your PHTML template.
2. **Naming Convention**: While `viewModel` is a commonly used name, it's not strictly necessary. You're correct that it could be anything you prefer. However, adopting a consistent naming convention, such as `viewModel`, can improve code readability and maintainability, especially when working in a team or across multiple projects. It's a good practice to use meaningful and descriptive names for variables and classes to enhance code clarity.
3. **Pattern Considerations**: Introducing View Models as a pattern in Magento 2 can indeed provide benefits in terms of separation of concerns and code organization. By adopting a consistent naming convention and utilizing View Models for injecting dependencies into blocks, you can enhance the modularity and testability of your codebase.
In summary, while the choice of naming convention for View Models is flexible, adopting a consistent approach like `viewModel` can facilitate code comprehension and collaboration. Leveraging View Models as a pattern can contribute to cleaner code architecture and improved development workflows.
If you have further