Magento-Pasar datos entre un controlador y un bloque


Pregunta muy rápida y simple, pero no puedo encontrar una respuesta decente a esto: ¿Cuál es la mejor manera de pasar datos de un controlador a un bloque en Magento?

En caso de que haga una diferencia, estoy cargando el diseño de la siguiente manera:

 $this->loadLayout(array('default', 'myModule_default'));

    $this->_initLayoutMessages('customer/session')
         ->_initLayoutMessages('catalog/session')
         ->renderLayout();

Debo añadir, que he estado utilizando el registro de la siguiente manera:

En el controlador:

Mage::register('data', $data);

En el bloque:

$data = Mage::registry('data');

No estoy seguro de si esta es la mejor manera de hacerlo.

Author: Jonathan Day, 2010-10-24

6 answers

No lo haces.

En el enfoque MVC de Magento, no es responsabilidad del controlador establecer variables para la vista (en el caso de Magento, la vista es Diseño y bloques). Los controladores establecen valores en los Modelos, y luego los bloques leen de esos mismos modelos. En la visión del mundo de Magento, tener un Bloque que confía en el controlador haciendo una cosa específica es un acoplamiento apretado, y debe evitarse.

El trabajo de su controlador es hacer ciertas cosas a los Modelos, y luego decirle al sistema es hora de renderizar el diseño. Eso es. Es su trabajo de Diseño / Bloques para mostrar una página HTML de una cierta manera dependiendo del estado de los Modelos del sistema.

Entonces, si quisiera emular los comportamientos tradicionales de PHP MVC,

  1. Crear una clase de modelo simple de la que hereda Varien_Object

  2. En el controlador, instanciar ese objeto usando el Mage::getSingleton('foo/bar')

  3. Establecer valores en el Modelo usando el getter/setters mágicos (obtienes estos en objetos que heredar de Varien_Object), o setData, etc.

  4. En los Bloques, instanciar el Modelo de nuevo con un Mage::getSingleton('foo/bar') y leer los valores de nuevo.

Cuando instancies un Modelo con Mage::getSingleton(...) Magento instanciará el objeto como un singleton. Por lo tanto, si vuelve a instanciar un objeto (de nuevo con Mage::getSingleton('foo/bar')), está recuperando el mismo objeto.

 81
Author: Alan Storm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-24 02:10:51

Si está utilizando bloques que heredan Mage_Core_Block_Template (es decir, que usan una plantilla para mostrar) puede asignar datos usando el método assign (), una vez que los bloques han sido instanciados por loadLayout()

$this->loadLayout(array('default', 'myModule_default'));

$this->getLayout()->getBlock('your.block.name.in.the.layout')->assign('data', $data);

Entonces, en el .plantilla phtml, simplemente puede usar

<?php echo $data ?>

Esto no se usa muy a menudo en magento, pero ya que se implementa como métodos públicos y por lo tanto se declara estable, creo que está bien hacerlo. Esa es también la razón para que la convención comience variables declaradas en una plantilla con un guion bajo (por ejemplo, $_product = $this->getProduct()), para que puedan distinguirse de las variables asignadas.

 35
Author: Vinai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-02 14:11:47

Lo que ha funcionado para mí en el es establecer la variable en el controlador haciendo:

Mage::register('variable', 'value');

Y luego en la vista recuperaría el valor usando el siguiente código:

$variable = $this->getVariable();
 4
Author: Josh Pennington,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-23 23:51:59

Estás en el camino correcto usando el enfoque Mage::registry(). La otra opción es usar getters y setters automáticos, por ejemplo $this->setRandomVariableName($data) en el controlador y luego en el bloque use $this->getRandomVariableName(). No he investigado si terminan en la misma ubicación en la pila (supongo que en la sesión, ya que son específicas de la solicitud), pero logran el mismo objetivo en el código.

El uso de los getters y setters ocasionalmente puede ser confuso, ya que puede parecer que está accediendo a los datos a través del OR en lugar de una variable de sesión" temporal", por lo que puede tomar una decisión de consistencia de estilo de codificación para usar Mage::registry para esos tipos de variables. Tu elección realmente.

 2
Author: Jonathan Day,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-23 22:22:17

Puede usar el par setData / getData para algunos valores. Usé setData en el controlador y getData en el bloque.

 0
Author: Taras,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-12 09:04:24

@ Dibujado Con un poco de fondo en JavaServer Caras y bastante nuevo en PHP / Magento Me gustaría decir que la

"'share nothing' architecture of PHP",

Ver PHP no es Java: Session Management Whitepaper", lleva al hecho de que todos los objetos (e incluso clases) en PHP tienen el alcance "request".

Si tengo Alans punto entonces él aconseja utilizar

  • un objeto de modelo 'con estado' que tiene algunos datos en sus atributos que no necesariamente se almacenan en la base de datos
  • y el patrón singleton, mediante el uso de Mage::getSingleton, para hacer que este modelo con estado, que se instanciaen el controlador, sea accesible al bloque y por lo tanto en la plantilla real que renderiza la salida.

Y dado que una herramienta como MTool reduce el tiempo para crear un nuevo modelo, esto realmente parece tener sentido.

 0
Author: paderEpiktet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-05 12:52:43