In this tutorial, we will explain how to use viewModel in Magento 2. Magento implemented viewModel in Magento 2.2. Whenever you are planning to add codes in a template file without using an object manager or overriding the block file, viewModel is highly useful. It will allow passing data and additional functionality to the template file.
For an instance, in topmenu.phtml file if you want to get some customer-related data, you will require to get it by the object manager. But if you want to get it without object manager and use it with the construct method, you need to use viewModel method.
Step to use viewModel in Magento 2
1) First of all, Let’s assume that you have created a simple module. Now, you need to create a default.xml file at app/code/MageDelight/Helloworld/view/frontend/layout/ and paste the below code:
<?xml version="1.0"?> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceBlock name="catalog.topnav" template="Magento_Theme::html/topmenu.phtml"> <arguments> <argument name="viewModel" xsi:type="object">MageDelight\Helloworld\ViewModel\Customer</argument> </arguments> </referenceBlock> </body> </page>
Here, you need to use block of topmenu.phtml file as referenceBlock. You can use your block name for viewModel in which phtml file you want to pass custom data. To call viewModel you need to pass the argument inside that referenceBlock and pass viewModel file class as an object.
2) Now, create Customer.php file at app/code/MageDelight/Helloworld/ViewModel/ and paste the below code:
<?php namespace MageDelight\Helloworld\ViewModel; class Customer implements \Magento\Framework\View\Element\Block\ArgumentInterface { /** * @var \Magento\Customer\Model\CustomerFactory */ protected $customerFactory; /** * @param \Magento\Catalog\Model\CustomerFactory $customerFactory */ public function __construct( \Magento\Catalog\Model\CustomerFactory $customerFactory ) { $this->customerFactory = $customerFactory; } public function getCustomerById($id) { $customerObj = $this->customerFactory->create()->load($id); return $customerObj; } }
Here, you can see that we can inject class without extending parent class inside the construct. So, it’s a plus point to viewmodel for pass data and faster to receive data. You need to implement the \Magento\Framework\View\Element\Block\ArgumentInterface interface class for view model.
3) Now, you can use that function in topmenu.phtml file using this below way:
$viewModel = $block->getData('viewModel'); $customerData = $viewModel->getCustomerById(1); // pass customer id echo $customerData->getEmail();
You can access viewModel via the getData() method by name of the argument and then, you can access the function of the viewModel file.
That’s it !!!