Magento 2: pasar variables de la acción del controlador a "Ver"

12

En Magento 1, si desea pasar datos de su acción Controlador a la "Vista" (es decir, un bloque en su diseño, puede hacerlo)

  1. Agregue un valor / objeto al registro global a través de Mage::register

  2. Obtener directamente un objeto de bloque y establecer propiedades de datos en el objeto de bloque obtenido después de ejecutar loadLayout

  3. Llame a métodos sobre objetos de bloque en phtmlarchivos y haga que los objetos de bloque usen la capa de modelo / base de datos para leer datos previamente guardados en la acción del controlador

El uso de métodos de objetos de bloque para leer de la base de datos todavía parece funcionar en Magento 2, lo cual es apropiado para ciertos tipos de operaciones. Sin embargo,

  1. Ya no hay un registro global en Magento 2 (¿o sí?)

  2. El sistema de diseño ahora funciona creando un objeto de página a través de una fábrica, y no puede tomar referencias de bloque de la misma manera que en Magento 1

¿Es posible en Magento 2 pasar datos directamente desde una acción del controlador a una vista? ¿O es esto un patrón demasiado directo para el nuevo y valiente mundo Design Pattern ™ de Magento? Si este es un patrón demasiado directo, ¿qué debería estar haciendo si hay alguna información calculada que queremos mostrar en una plantilla, pero no queremos almacenar esa información en un sistema con estado (es decir, no queremos guardarla en el base de datos)

Puedo pensar en una forma diferente de hackear esto juntos, pero estoy interesado en cómo Magento 2 quiere que lo hagas.

Nota : Me doy cuenta de que es posible recuperar una instancia de bloque en una acción de controlador usando algo como esto

$resultPage = $this->resultPageFactory->create();    
$block = $resultPage->getLayout()->getBlock('catalog.wysiwyg.js');        

var_dump(spl_object_hash($block));

El código central de Magento 2 hace esto a menudo. Sin embargo, el objeto de bloque obtenido en el objeto controlador parece ser un objeto diferente del que está disponible en una phtmlplantilla a través de cualquiera $thiso $block(el primero ( $this) parece ser el objeto que realmente representa la plantilla, mientras que el posterior ( $block) parece ser una instancia del tipo de bloque Magento).

#File: path/to/template.phtml
var_dump(spl_object_hash($block));
var_dump(spl_object_hash($this));

Digo "parece ser" porque si configuro los datos en el método de acción del controlador, no está disponible en la phtmlplantilla, y si comparo los spl_object_hashresultados anteriores, obtengo tres valores hash diferentes. Sin embargo, soy lo suficientemente nuevo en todo esto como para que lo anterior sea otro error que haya cometido, por lo que si ha podido configurar los datos en bloques y buscarlos en una plantilla, me encantaría saberlo !

Alan Storm
fuente

Respuestas:

17

Con respecto al n. ° 1, el registro todavía existe, muy similar a lo que sabes de Magento 1. Simplemente se movió. Ver:\Magento\Framework\Registry

Agréguelo a su constructor mediante la inyección de dependencia, y luego puede usar sus métodos $registry->register($key, $value)y $registry->registry($key)métodos familiares para almacenar / acceder a los datos.

Recomiendo hurgar en el espacio de nombres \ Magento \ Framework si aún no lo ha hecho. Mucho de lo que antes era accesible desde Mage o App todavía está allí, solo se separó.

En cuanto a las mejores prácticas, no puedo responder eso, pero espero que la respuesta sea mantener la mayor cantidad de lógica fuera del controlador como sea posible. Mirar el núcleo es probablemente tu mejor apuesta. Por ejemplo, consulte la página de edición de la dirección del cliente: controlador básico ; bloque extenso, incluido extraer la identificación de la dirección y cargarla, si es necesario. Manejan eso directamente en el bloque; no lo hacen en el controlador y luego lo pasan.

Ryan Hoerr
fuente
2
El truco, por supuesto, es saber qué partes del núcleo mirar y cuáles ignorar :) ¡Gracias por los punteros, +1 por información útil!
Alan Storm
1
+1 para el último párrafo. Si necesita compartir algún valor calculado, coloque el comportamiento de cálculo para separar el objeto y llamarlo desde los bloques que requieren ese valor. Se desaconseja el registro porque es un estado mutable global y nunca está seguro de lo que obtendrá de allí. El direccionamiento directo de los bloques desde la acción también se desaconseja porque nunca está seguro si el bloque está presente en una página (el diseño puede matarlo)
Anton Kril
@AntonKril, ¿qué tal los ayudantes de renderizador de página? Ayudante de página de CMS, ayudante de vista de producto, ¿están destinados a separar la representación de la solicitud HTTP?
Ivan Chepurnyi
5

Usted debe no pasar variables de Acción controlador para Vista. Use block to para pasar Variables a Vista (motor de plantillas).

Kandy
fuente
¿Por qué? ¿Cómo podría pasar obtener / publicar parámetros del bloque para ver? ¿La mayoría de la lógica no los pasa del controlador a la vista?
LucScu
Utilice el objeto de solicitud en bloques. Si bloquea obtener datos del controlador a través del Registro, no puede usarlo para bloquearlo con otros controladores. Se llama acoplamiento temporal y sus malas prácticas
KAndy
Uso $ block-> asignar () para pasar los parámetros de la solicitud del controlador al bloque. ¿Es también una mala práctica?
LucScu
El direccionamiento directo de bloques desde la acción también se desaconseja porque nunca está seguro de si el bloque está presente en una página.
KAndy
En mi caso, estoy seguro, porque es un escenario personalizado donde el controlador, el diseño y el bloque solo están controlados por mi código, por lo que creo que son los parámetros de la solicitud de paso lógico de controlador a bloque. Gracias por sus respuestas!
LucScu