View Models en Magento 2

View Models en Magento 2

¿Qué son los View models ?

Un “view model” es una abstracción de la vista, que nos permitirá añadir la lógica a nuestra vista en una clase separada, al igual que hacíamos con los “blocks”.

¿Cómo se usan?

Anteriormente a la versión 2.2 de Magento, y cómo podemos ver en distintas partes del core de Magento, para pasar a un template información/datos, usamos los “blocks”, que eran pasados al template a través del atributo class de la instrucción del layout <block>.

Ejemplo:

<block class="Magento\Checkout\Block\Onepage" name="checkout.root" template="Magento_Checkout::onepage.phtml" />

Estaclass debía heredar de \Magento\Framework\View\Element\Template.

Ahora, con los view model, no especificaremos el class a nuestros bloques, ya que por defecto Magento indicará que la clase del bloque será \Magento\Framework\View\Element\Template.

Tanto si queremos crear un nuevo bloque, como si queremos hacer referencia a uno existente, el método es el mismo:

<!-- Añadir view model a un nuevo bloque --> 
<block name="mi.nuevo.bloque" template="JLNarvaez::vista.phtml">
    <arguments>
        <argument name="view_model" xsi:type="object">JLNarvaez\Prueba\ViewModel\MiPrimerViewModel</argument>
    </arguments>
</block>

<!-- Añadir view model a uno existente -->
<referenceBlock name="additional.product.info" template="JLNarvaez::vista.phtml">
    <arguments>
        <argument name="view_model" xsi:type="object">JLNarvaez\Prueba\ViewModel\MiPrimerViewModel</argument>
    </arguments>
</referenceBlock>

Para crear nuestra clase View Model lo único que necesitaremos es que implemente la interfaz \Magento\Framework\View\Element\Block\ArgumentInterface.

<?php

namespace JLNarvaez\Prueba\ViewModel;

class MiPrimerViewModel implements \Magento\Framework\View\Element\Block\ArgumentInterface
{
    public function getSaludo()
    {
      return '¡Bienvenidos!';
    }
}

Entonces, a la hora de recogerlo en nuestro template app/code/JLNarvaez/Prueba/view/frontend/templates/vista.phtml, lo haremos de la siguiente manera:

<?php

/** @var $viewModel \JLNarvaez\Prueba\ViewModel\MiPrimerViewModel */
$viewModel = $block->getViewModel();
?>

<div class="container">
    <h1><?= $viewModel->getSaludo() ?></h1>    
</div>

Cabe destacar que, obviamente, en nuestra clase View model, podremos hacer uso del constructor para inyectar las clases que nos hagan falta para hacer la lógica que queramos.

¿Por qué usar View model?

Es recomendado por la documentación oficial de Magento, a partir de la versión 2.2.

Si usamos el atributo class creando una clase que herede de \Magento\Framework\View\Element\Template, tendremos que crear si o si la función __construct y llamar al parent::__construct con los parámetros que le hagan falta a la clase padre. En cambio, con los View model no tendremos ese problema, ya que crearemos el __construct si realmente lo necesitamos, y además, con lo que únicamente nos haga falta.

Además de esta manera, podremos añadir varios view models a nuestros templates, sin tener que depender de una sola clase.

También, si queremos hacer un cambio menor en un bloque ya existente, nos ahorraremos tener que hacer un <preference> a la clase del bloque ya existente, y simplemente le pasaremos nuestro View model.

Si quieres saber más sobre View Model puedes visitar la documentación oficial de Magento.

Jose Luis
Jose Luis
Magento 2 Certified Developer