Magento 2: View Model
A view model is a class that allows you to pass data and additional functionality from a place that represents a business logic to a template. It can also provide data loaded from an entity, such as a product.
The View Model class can hold calculation logic, data lookups, and object fetches and passes them directly to a template, so the template’s reasoning can be as simple as possible.
View Models are usually located in the module’s directory called ViewModel. However, the location of view model classes is not limited to a ViewModel guide. You can create as many view models as needed to provide a required set of separate classes with its logic.
In this post you will learn:
- What is a View Model?
- How to use the View Model?
- When to use a View Model?
View Model Example
The concept of a view model is simple and, at the same time, powerful. Let’s jump into the example to understand the creation flow better. We must create a PHP class in the ViewModel directory to implement a view model.
class ProductViewModel { private $resource; public function __construct(Resource $resource) { $this->resource = $resource; } public function getProductBySku(string $sku): ProductInterface { return $this->resource->load($sku, ‘sku’); } }
The only requirement is that the ProductViewModel class must implement Magento\Framework\View\Element\Block\ArgumentInterface. Let’s add it.
use Magento\Framework\View\Element\Block\ArgumentInterface; class ProductViewModel implements ArgumentInterface { //... }
Once the view model class is created, we must add it to a layout XML file. So that during layout rendering, it will find the view model class, instantiate it, and add it to the pool of Block class dependencies.
A Layout XML file should be located in the module’s view/frontend/layout directory. We’ve discussed different layout configuration areas in the Template and Layout rendering lesson. Check the study to understand better frontend and adminhtml directory locations for layout xml files.
Inside the layout file, we have to add a new node in the and. The two attributes should be added to the node, the name of the view model variable and its type; the type should always be set to an object since we pass a class name that has to be initiated as a view model.
<?xml version="1.0"?>
<page>
<body>
<referenceBlock name="block.name">
<arguments>
<argument
name="view_model"
xsi:type="object">MageMastery\ViewModelExample\ViewModel\ProductViewModel</argument>
</arguments>
</referenceBlock>
</body>
</page>
From the example above, a “block.name” can be a block’s name where we want to add a View Model class.
Inside the node, we have to provide the full class name of the view model. Remember, all objects injected to block arguments as view models should implement the ArgumentInterface interface.
Finally, the template of the block to which we’ve added the view model class can get access to the view model. The view model object is passed as an argument of the Template object. It can be accessed via the getData() method by providing the name of the idea we’ve provided in the layout XML file.
/** @var ProductData $productData */
$productData = $block->getData(“view_model”);
After we’ve received access to the view model, we can start using it in the template.
<h1><?= $productData->getProductBySku(‘sku’); ?></h1>
As a result, the data provided from the view model class is rendered by a template.
View Model Checklist
Let’s recap what we need to create and use a view model.
- Create a PHP class
- Add an ArgumentInterface
- Add a PHP Class into a layout XML
- Retrieve a View Model in a template
- Use View Model public methods
When to use a View Model?
A view model should be used every time you pass data from storage or the other object to a template for rendering. It includes calculation logic, data lookups, object fetches, etc.
A view model has to be used instead of a block, so your code will be less dependent on block changes in the Magento 2 framework.
Conclusion
A view model in Magento 2 is a powerful mechanism that allows us to represent and provide data ready for rendering in a template. It provides a simple tool recommended every time a UI customization should be added.