web-dev-qa-db-fra.com

Magento - Passage de données entre un contrôleur et un bloc

Question vraiment rapide et simple, mais je ne trouve pas de réponse décente à cela - Quelle est la meilleure façon de transmettre des données d'un contrôleur à un bloc dans Magento.

Dans le cas où cela fait une différence, je charge la mise en page comme suit:

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

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

Je dois ajouter que j'ai utilisé le registre comme suit:

Dans le contrôleur:

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

Dans le bloc:

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

Je ne sais pas si c'est la meilleure façon de le faire.

46
Drew Hunter

Non.

Dans l'approche MVC de Magento, il n'est pas de la responsabilité du contrôleur de définir des variables pour la vue (dans le cas de Magento, la vue est Disposition et blocs). Les contrôleurs définissent des valeurs sur les modèles, puis les blocs lisent à partir de ces mêmes modèles. De l'avis de Magento sur le monde, avoir un bloc reposant sur le contrôleur qui fait une chose spécifique est un couplage étroit, et devrait être évité.

Le travail de votre contrôleur consiste à effectuer certaines tâches sur les modèles, puis à indiquer au système le temps de rendu de la mise en page. C'est ça. C'est votre travail de mise en page/blocs d'afficher une page HTML d'une certaine manière en fonction de l'état des modèles du système.

Donc, si je voulais émuler les comportements traditionnels PHP MVC, je

  1. Créez une classe Model simple dont hérite Varien_Object

  2. Dans le contrôleur, instanciez cet objet à l'aide de la Mage::getSingleton('foo/bar')

  3. Définissez des valeurs sur le modèle en utilisant le getter/setters magiques (vous les obtenez dans des objets qui héritent de Varien_Object), Ou setData, etc.

  4. Dans les blocs, instanciez à nouveau le modèle avec une Mage::getSingleton('foo/bar') et relisez les valeurs.

Lorsque vous instanciez un modèle avec Mage::getSingleton(...) Magento instanciera l'objet en tant que singleton. Donc, si vous réinstanciez un objet (à nouveau avec Mage::getSingleton('foo/bar')), vous récupérez le même objet.

83
Alan Storm

Si vous utilisez des blocs qui héritent Mage_Core_Block_Template (c'est-à-dire qui utilisent un modèle à afficher), vous pouvez affecter des données à l'aide de la méthode assign (), une fois les blocs ont été instanciés par loadLayout()

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

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

Ensuite, dans le modèle .phtml, vous pouvez simplement utiliser

<?php echo $data ?>

Ceci n'est pas utilisé très souvent dans magento, mais comme il est implémenté en tant que méthodes publiques et donc déclaré stable, je pense que c'est bien de le faire. C'est également la raison pour laquelle la convention démarre les variables déclarées dans un modèle avec un trait de soulignement (par exemple $_product = $this->getProduct()), afin qu'elles puissent être distinguées des variables affectées.

35
Vinai

Ce qui a fonctionné pour moi dans le, c'est de définir la variable dans le contrôleur en faisant:

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

Et puis dans la vue, vous récupérez la valeur en utilisant le code suivant:

$variable = $this->getVariable();
4
Josh Pennington

Vous êtes sur la bonne voie en utilisant l'approche Mage::registry(). L'autre option consiste à utiliser des getters et setters automatiques, par ex. $this->setRandomVariableName($data) dans le contrôleur, puis dans le bloc, utilisez $this->getRandomVariableName(). Je n'ai pas cherché à savoir s'ils se retrouvent au même emplacement dans la pile (je suppose dans la session car ils sont spécifiques à la demande), mais ils atteignent le même objectif dans le code.

L'utilisation des getters et setters peut parfois être source de confusion car il peut sembler que vous accédez aux données via l'ORM plutôt qu'une variable de session "temporaire", vous pouvez donc prendre une décision de cohérence de style de codage à utiliser Mage::registry pour ces types de variables. Votre choix vraiment.

2
Jonathan Day

@Drew Avec quelques antécédents dans JavaServer Faces et plutôt nouveau dans PHP/Magento, je voudrais dire que le

"l'architecture 'ne rien partager' de PHP",

voir PHP n'est pas Java: Livre blanc sur la gestion des sessions " , conduit au fait que tous les objets (et même les classes) dans PHP ont la portée" request ".

Si j'ai obtenu le point Alans, il conseille d'utiliser

  • un objet de modèle "avec état" qui contient des données dans ses attributs qui ne sont pas nécessairement stockées dans la base de données
  • et le modèle singleton, en utilisant Mage :: getSingleton, pour rendre ce modèle avec état, qui est instancié dans le contrôleur, accessible au bloc et donc dans le modèle réel qui rend la sortie.

Et puisqu'un outil comme MTool réduit le temps de création d'un nouveau modèle, cela semble vraiment logique.

0
paderEpiktet

Vous pouvez utiliser la paire setData/getData pour certaines valeurs. J'ai utilisé setData dans le contrôleur et getData dans le bloc.

0
Taras