What is ViewModel ?
ViewModel is a PHP class. That fulfills a single or multiple object needs without extending the original block.
It avoids unnecessary overriding of block and block constructor arguments. ViewModel has required resources only. So, we can get data faster compared to block and helper classes.
How to implement ViewModel ?
In layout we can define ViewModel in block arguments with xsi:type as object. We can pass multiple ViewModel in a single block.
Let’s use this FirstModule and add new ViewModel in layout. Adding this RS\FirstModule\ViewModel\Calculate to message block.
<?xml version="1.0"?>
<!-- file path: MAGENTO_ROOT/app/code/RS/FirstModule/view/frontend/layout/first_module_first_index.xml -->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="page.main.title">
<action method="setPageTitle">
<argument translate="true" name="title" xsi:type="string">First Module</argument>
</action>
</referenceBlock>
<referenceContainer name="content">
<block class="Magento\Framework\View\Element\Template" name="message" template="RS_FirstModule::message.phtml">
<arguments>
<argument name="view_model" xsi:type="object">\RS\FirstModule\ViewModel\Calculate</argument>
</arguments>
</block>
</referenceContainer>
</body>
</page>
Create ViewModel class
As per the Magento 2 standards, We create ViewModel class under ViewModel directory in your custom module. Basically we create this ViewModel for simple calculation.
For creating ViewModel we need implement the ArgumentInterface (\Magento\Framework\View\Element\Block\ArgumentInterface).
<?php
//file path: MAGENTO_ROOT/app/code/RS/FirstModule/ViewModel/Calculate.php
namespace RS\FirstModule\ViewModel;
use Magento\Framework\View\Element\Block\ArgumentInterface;
class Calculate implements ArgumentInterface
{
/**
* Return the sum of array arguments
*
* @param mixed $args
* @return int
*/
public function sum($args)
{
$tot = 0;
foreach ($args as $argsItem) {
$tot += $argsItem;
}
return $tot;
}
}
How to access ViewModel in template file ?
After declare and create ViewModel. Now we use that ViewModel to our template file. When we add any ViewModel to any block using layout, It’s add new argument value in block. So we can use that argument value using setter getter methods.
Let’s access ViewModel.
<?php
// file path: MAGENTO_ROOT/app/code/RS/FirstModule/view/frontend/templates/message.phtml
/**
* Product list template
*
* @var $block \Magento\Framework\View\Element\Template
* @var \Magento\Framework\Escaper $escaper
*/
?>
<?php
$viewModel = $block->getViewModel(); // Or you can use $block->getData('view_model')
$subjectMarks = [
"php" => 75,
"java" => 80,
".net" => 85
];
?>
<?= $escaper->escapeHtml(__("This is my first Magento 2.x Module")); ?>
<br />
<?= $escaper->escapeHtml(__("We can calculate sum using ViewModel.")) ?>
<br />
<?= $escaper->escapeHtml(__("Sum is: %1", $viewModel->sum($subjectMarks))) ?>
Using getViewModel() or getData(‘view_model’) we can get the ViewModel object. We can set any of the name instead of the view_model. it’s not necessary to set name as view_model.
Let’s check the output: