A view model is a reflection of the view, uncovering public properties and orders. It permits designers to offload elements and business rationale from block classes into isolated classes that are more straightforward to keep up with, test, and reuse.
View models are accessible in Adobe Commerce and Magento Open Source 2.2 and later.
Magento 2: how to use viewmodels
I assume that you have already created a basic module and now you need to use a view model.
You need to create a layout file inside your theme / module.
Let’s create a layout file in custom module:
VendorName/ModuleName/view/<areaname>/layout directory.
<block class="ModuleName\VendorName\Block\ClassName" name="block_name" template="ModuleName_VendorName::templatename.phtml">
<arguments>
<argument name="view_model" xsi:type="object">
VendorName\ModuleName\ViewModel\ViewModel
</argument>
</arguments>
</block>
You need to create a view model class inside vendorName/ModuleName/ViewModel/ directory
ViewModel Class implements interface Magento\Framework\View\Element\Block\ArgumentInterface
Example
Let’s create the layout file sbdevblog_products_view.xml inside SbDevBlog/Catalog/view/frontend/layout
<?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>
<referenceContainer name="content">
<block class="Magento\Framework\View\Element\Template" name="order_items_list" template="SbDevBlog_Catalog::simple.phtml">
<arguments>
<argument name="view_model" xsi:type="object">SbDevBlog\Catalog\ViewModel\SimpleItemsViewModel</argument>
</arguments>
</block>
</referenceContainer>
</body>
</page>
Let’s create the ViewModel File with name SimpleItemsViewModel.php inside SbDevBlog/Catalog/ViewModel Directory
<?php
namespace SbDevBlog\Catalog\ViewModel;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\ResourceModel\Product\Collection;
use Magento\Framework\View\Element\Block\ArgumentInterface;
use SbDevBlog\Catalog\Services\GetSimpleProductsServices;
class SimpleItemsViewModel implements ArgumentInterface
{
/**
* @var GetSimpleProductsServices
*/
private GetSimpleProductsServices $simpleProductsServices;
/**
* Constructor
*
* @param GetSimpleProductsServices $simpleProductsServices
*/
public function __construct(
GetSimpleProductsServices $simpleProductsServices
) {
$this->simpleProductsServices = $simpleProductsServices;
}
/**
* Get Simple Product Collection
*
* @return Collection
*/
public function getSimpleProducts():Collection
{
return $this->simpleProductsServices->getSimpleProducts();
}
/**
* Get Add To Cart Url
*
* @param Product $product
* @return string
*/
public function getAddToCartUrl(Product $product):string
{
return $this->simpleProductsServices->getAddToCartUrl($product);
}
/**
* Formatted Price
*
* @param string $price
* @return string
*/
public function getFormmatedPrice($price):string
{
return $this->simpleProductsServices->getFormattedPrice($price);
}
/**
* Get Product Image URl
*
* @param Product $product
* @return string
*/
public function getProudctImageUrl(Product $product):string
{
return $this->simpleProductsServices->getProudctImageUrl($product);
}
}
Let’s create the template file with name simple.phtml inside SbDevBlog/Catalog/view/frontend/templates/ in which we will use the ViewModel class created above.
<?php
/**
* @copyright Copyright (c) sbdevblog (http://www.sbdevblog.com)
*/
/** @var Magento\Framework\View\Element\Template $block */
/** @var \Magento\Framework\Escaper $escaper */
$viewModel = $block->getViewModel();
$productCollection = $viewModel->getSimpleProducts();
?>
<table>
<thead>
<th>
<input type="checkbox" class="all_products_checked" />
</th>
<th>
<?=$escaper->escapeHtml(__("Thumbnail")) ?>
</th>
<th>
<?=$escaper->escapeHtml(__("Product Name")) ?>
</th>
<th>
<?=$escaper->escapeHtml(__("Price")) ?>
</th>
<th>
</th>
</thead>
<tbody>
<?php
foreach ($productCollection as $product) {
?>
<tr>
<td>
<input type="checkbox" class="products_checked"
id="product_<?=$escaper->escapeHtml($product->getId())?>"
name="products[]" value="<?=$escaper->escapeHtml($product->getId()) ?> " />
</td>
<td>
<a href="<?=$escaper->escapeUrl($product->getProductUrl()) ?>">
<img src="<?=$escaper->escapeUrl($viewModel->getProudctImageUrl($product)) ?>" />
</a>
</td>
<td>
<a href="<?=$escaper->escapeUrl($product->getProductUrl()) ?>">
<?=$escaper->escapeHtml(__($product->getName())) ?>
</a>
</td>
<td>
<?=$escaper->escapeHtml($viewModel->getFormmatedPrice($product->getPrice())) ?>
</td>
<td>
<form data-role="tocart-form"
action="<?=$escaper->escapeUrl($viewModel->getAddToCartUrl($product)); ?> ?>"
method="post">
<?=$block->getBlockHtml('formkey')?>
<div class="btn">
<button type="submit" title="Add to Cart" class="action tocart primary">
<span><?=$escaper->escapeHtml(__("Add to Cart"))?></span>
</button>
</div>
</form>
</td>
</tr>
<?php
}
?>
<tfoot>
<tr>
<td>
<form action="<?=$escaper->escapeUrl($block->getUrl("sbdevblog/products/addtocart")) ?>"
method="post" id="multiplecartform">
<?=$block->getBlockHtml('formkey')?>
<input type="hidden" id="product_ids" name="product_ids"/>
<div class="btn">
<button type="button" title="Add to Cart" class="multiplecart primary">
<span><?=$escaper->escapeHtml(__("Add to Cart"))?></span>
</button>
</div>
</form>
</td>
</tr>
</tfoot>
</tbody>
</table>
<script>
require(['jquery'], function($) {
jQuery(".multiplecart").on("click", function(){
var product_ids = [];
document.querySelectorAll('.products_checked').forEach(function(elem) {
if(elem.checked && elem.value !== undefined){
product_ids.push(elem.value);
}
});
if(parseInt(product_ids.length) === 0) {
alert("Please Check At Least One Checkbox");
return;
}
var products = JSON.stringify(product_ids);
$("#product_ids").val(JSON.parse(products));
$("#multiplecartform").submit();
});
jQuery(".all_products_checked").on("click", function(){
var aa = document.querySelectorAll('.products_checked');
for (var i = 0; i < aa.length; i++){
aa[i].click();
}
})
});
</script>
Thanks for reading the post – magento 2 how to use viewmodels.
Click here to send the attachment.
The use of helpers in templates is discouraged. It is recommended to use view models instead.
Note: Please verify the code of this blog and the relevant git repository before using it in production.
🙂 HAPPY CODING 🙂
One thought on “Magento 2: How to use ViewModels?”