2012-03-19 12 views
13

¿Alguien puede explicar esto?En Magento, ¿cómo toman los bloques los datos de los modelos?

Déjame decirte lo que sé. Si los primeros tres puntos son buenos, explique el 4 punto.

  1. Solicitud ven al controlador.
  2. En la acción del controlador, iniciamos los modelos.
  3. Modelos recoge o genera toda la información necesaria mediante la conexión a la base de datos, etc.

¿Qué pasa después de eso?

  1. ¿Cómo los modelos transfieren datos a Blocks, o los Blocks obtienen datos de los modelos?

  2. plantillas de obtener los datos preparados y muestran en la pantalla

    • Además, hace la solicitud siempre se remonta al controlador de nuevo?

Por favor explique. Estoy confundido en varios lugares.

Respuesta

33

Nada transfiere datos a los bloques. Después de una acción de controlador ha hecho su interactuando modelo, que es responsable de

  1. Carga de un objeto de presentación (que, indirectamente, cargas y crea objetos de bloque)

  2. Dile a ese objeto de diseño para representar una página.

La mayoría de las acciones del controlador Magento hacen esto con dos llamadas al final de una acción del controlador.

$this->loadLayout(); 
$this->renderLayout(); 

En Magento, nada establece datos en la vista. En cambio, la vista (es decir, los objetos de bloque) pregunte al sistema por datos. Puede ver un ejemplo de esto en la clase de bloque Mage_Tag_Block_Customer_View.

#File: app/code/core/Mage/Tag/Block/Customer/View.php  
... 
public function getTagInfo() 
{ 
    if (is_null($this->_tagInfo)) { 
     $this->_tagInfo = Mage::getModel('tag/tag') 
      ->load($this->getTagId()); 
    } 
    return $this->_tagInfo; 
}  
... 

Aquí, el método de este bloque getTagInfo pide al modelo directamente para su conocimiento. De esta forma, el desarrollador de plantilla front-end tiene acceso a un

$this->getTagInfo(); 

método. También tengo en good authority que el método _prepareLayout de un bloque es el lugar perfecto para poner la mayoría, sino todo, de su código de búsqueda de datos en un bloque.

Un segundo patrón que verá utilizado es el patrón de registro de Magento. Este es un sistema de Magento que le permite establecer una variable global en todo el sistema (pero no en PHP).

Mage::register('foo', 'some value'); 
echo Mage::registry('foo'); 

A veces un desarrollador de Magento se utilice el registro para establecer una variable en una acción del controlador, y luego agarrar está de vuelta en los bloques. Por ejemplo, en el controlador de factura de la consola de administración.

#File: app/code/core/Mage/Adminhtml/controllers/Sales/Order/InvoiceController.php 
protected function _initInvoice() 
{ 
    ... 
    $invoice = Mage::register('current_invoice', $invoice); 
    return $invoice; 
}  

y luego un bloque lo referenciará más adelante.

#File: app/code/core/Mage/Sales/Block/Order/Print/Invoice.php 
public function getInvoice() 
{ 
    return Mage::registry('current_invoice'); 
} 

no estoy loco por el patrón de registro, pero es utilizado por el equipo central, por lo que es probable que haya kosher.

Por último, si usted está mirando para emular el "punto de vista mudo" patrón usado en la mayoría de los marcos de PHP MVC, intentar algo como esto

$this->loadLayout(); 
$block = $this->getLayout()->getBlock('block_name'); 
$block->setSomeData('My Data'); 
$block->setData('alternate_syntax', 'Some other data'); 
$this->renderLayout(); 

y luego en el bloque y/o archivo de plantilla.

echo $this->getSomeData(); 
echo $this->getData('some_data'); 

echo $this->getAlternateSyntax(); 
echo $this->getData('alternate_syntax'); 

Después de llamar loadLayout, Magento habrá creado todos los objetos de bloque. Lo que está haciendo arriba es obtener referencia a un objeto de bloque específico y luego establecer sus datos.

Según los comentarios de Vinai a continuación, también hay un método de assign de bloque a considerar.

similares a setData, después de llamar loadLayout (o de la de un bloque _prepareLayout) método, se puede hacer algo como

$this->loadLayout(); 
$block = $this->getLayout()->getBlock('block_name'); 
$block->assign('my_view_var','Something for the view'); 
$this->renderLayout(); 

y luego en el expediente de su bloque phtml, serías capaz de salida que la Vista de variables

echo $my_view_var; 
+1

Alan, debemos comenzar a coordinar. Su respuesta es la mejor porque responde a la pregunta implícita de OP, que es "Magento, ¿YU NO RENDER COMO LA MAYORÍA de PHP MVC?", Algo que todos hemos preguntado ... :-D – benmarks

+1

Gracias Alan, lo resumió muy bien ! Lo único que se me ocurre agregar es el método 'assign()' del bloque de plantilla. Rara vez se usa, pero algunas personas lo prefieren 'setData()' porque coincide con el enfoque clásico de "asignar variables de plantilla". – Vinai

+0

Gracias Alan. Muy buena explicación, despejó la mayoría de mis dudas. – RIK

1

No, deja el controlador (el que controla la solicitud) y luego se mueve a las vistas, donde se representa. Una vez que la vista (bloque [s]) ha renderizado, la solicitud se ha terminado (salvo para la mayoría de los ayudantes de url, que no tienen lógica de la que hablar pero a veces se procesan en el controlador después de que se visualice la vista) a menos que tenga algún tipo de gancho desencadenado después.

utilizo this flowchart y this series (Alan Storm es el tipo ) para aprender acerca de Magento solicitud de enrutamiento.

+1

Técnicamente, una solicitud típica para el flujo de trabajo de renderizado utiliza 'renderLayout()', después de lo cual la ejecución continúa en la acción del controlador. Simplemente no es un caso común que el objeto de respuesta se altere en la acción del controlador después de 'renderLayout()', por lo que la siguiente línea suele ser el final del método y, por lo tanto, una vuelta al controlador frontal./hairsplit – benmarks

3
  1. correcta, a través del controlador y routers
  2. Frente
  3. No del todo. La implementación de ViewModel de Magento se facilita en parte al hacer que las vistas (Blocks) ejemplifiquen sus propios modelos.
  4. Sí, a través de los modelos de recursos.

Cuando los bloques se representan a través de la típica de flujo de $this->loadLayout()->renderLayout() en el controlador de acción, si utilizan plantillas, esas plantillas son include() d en tiempo de render.

Después de una llamada a renderLayout(), la ejecución aún está en el ámbito de la acción del controlador que hemos enviado, por lo que puede acceder a la respuesta representada obteniendo el objeto de solicitud.

puntos de la trama clave:

  1. índice.php llama Mage::run()
  2. Mage::run llamadas Mage_Core_Model_App::run()
  3. App::run() llamadas Mage_Core_Controller_Varien_Front, por primera vez su método init() que recoge y pone en marcha los routers, entonces dispatch() el que hace lo siguiente:

    a. La base de datos reescribe la URL

    b. Reescrituras de configuración (obsoleta)

    c. Haga coincidir la acción correcta del controlador a través del enrutador. La ejecución salta del controlador frontal al controlador de acción. Invocar bloques usando el diseño o manualmente pasará la ejecución para bloquear clases, modelos y plantillas, y luego (normalmente) regresaremos a la acción del controlador.

    d. Enviar el objeto de respuesta (con la suposición de que ha sido alterado por un controlador de acción).

Si nos fijamos en Mage_Core_Controller_Varien_Front::dispatch(); you'll see the call to $ this-> getResponse() -> sendResponse(); `lo que hará que se vacíe de salida, precedido por un evento (controller_front_send_response_before) que puede ser utilizado como un gancho para añadir o manipular cualquier cosa relacionado a la respuesta.

Cuestiones relacionadas