I am bit confuse about using viewModel in Magento. I am not getting exact difference between viewModel and Block. In which case using viewModel is best case?
Any help will be appreciated.
Magento Stack Exchange is a question and answer site for users of the Magento e-Commerce platform. It only takes a minute to sign up.Sign up to join this community
Magento veteran Jessie has a well famous blog on viewModel which you can find it here. It answers your question at the end. It says:
When to use ViewModels?
When would you want to use ViewModels? Well, when Magento 2.2 comes out and your code doesn't need to be backwards compatible with Magento 2.1 any more, my answer will be: Always! However, reality is that we most likely need to maintain backwards compatibility for some time. And the procedure above is a bit lengthy to follow if Block classes are still simple enough without any custom constructor.
I would say that you create some kind of ViewModel functionality as soon as you start overriding the Block constructor to inject your own dependency into it. A Block class that extends from a parent and simply reuses the parents dependencies is not that bad, as long as you don't have a huge dislike of $context. However, as soon as the Block becomes more complex, it's always better offload features to other classes. And ViewModels are meant to be the good addition to that.
Magento2, in its presentation level, uses Model-View-ViewModel(MVVM) design pattern. Here don't confuse the viewModel in the MVVM with the viewModel which is in your question.
image credits: wiki - mvvm
Here View layer is delivered by the phtml files and ViewModel layer is the block classes. It is the block classes responsibility to prepare the data that needs to present to the phtml file (View layer) from the models.
Now every block in Magento extends the class
Mage\Core\Block\Template in order to get the presentational power.
So this means, if you want to add some customization or change in the presentation of a block, then that change has to be done on the block class either through preference on plugins or by adding a new layer of block and phtml file.
In some occassions, you need to do a minor change in the presentation level, but in order to do it you may need to add a
new block or add a preference to the block in context. This seems costly as in either case, we need to deal with the
dependcy injection of the parent class
Mage\Core\Block\Template, which looks unfair in order to accomplish the change
you look forward to do in the presentational level.
Here is where the ViewModel in your question emerges with its true power. The concept is simple, we can inject any number
of viewModel layers into a block as an argument and thus can use them in the presentation level. The glory resides in the
fact that we can completely rid off the whole hell of dependency of the core class
Mage\Core\Block\Template inside a viewModel.
__construct of the ViewModel only holds those dependencies which require to prepare the data for the presentational phtml file.
This makes it cleaner and more reliable solution to do customization in the presentational level. Since the
__constuct of a
ViewModel does not want to deal with unwanted parental dependencies, this will eventually lead to the performance boost.
Thus, I would say, the viewModels is a well engineered, well-structured add-on to the blocks, which should be our best call when we do customization in the presentational level.
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()