cancel
Showing results for 
Search instead for 
Did you mean: 

Usage of viewModel in Blocks

SOLVED

Usage of viewModel in Blocks

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?

1 ACCEPTED SOLUTION

Accepted Solutions

Re: Usage of viewModel in Blocks

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();

View solution in original post

5 REPLIES 5

Re: Usage of viewModel in Blocks

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();

Re: Usage of viewModel in Blocks

Thanks, Anton. So we call it ViewModels. Smiley Happy I've been explaining this to my first students already and they are delighted.

Re: Usage of viewModel in Blocks

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>

 

Re: Usage of viewModel in Blocks

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

Re: Usage of viewModel in Blocks

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().