Magento 2: Passer des variables de l'action du contrôleur à «Afficher»

12

Dans Magento 1, si vous souhaitez transmettre des données de votre action Controller à la "Vue" (c'est-à-dire un bloc dans votre mise en page, vous pouvez)

  1. Ajouter une valeur / un objet au registre global via Mage::register

  2. Récupérer directement un objet bloc et définir les propriétés des données sur l'objet bloc récupéré après l'exécution loadLayout

  3. Appeler des méthodes sur des objets bloc dans des phtmlfichiers et faire en sorte que les objets bloc utilisent la couche modèle / base de données pour lire les données précédemment enregistrées dans l'action du contrôleur

L'utilisation de méthodes d'objet bloc pour lire à partir de la base de données semble toujours fonctionner dans Magento 2 - ce qui est approprié pour certains types d'opérations. cependant,

  1. Il n'y a plus de registre mondial dans Magento 2 (ou y en a-t-il?)

  2. Le système de disposition fonctionne maintenant en créant un objet de page via une usine, et vous ne pouvez pas saisir les références de bloc de la même manière que dans Magento 1

Est-il possible dans Magento 2 de transmettre des données directement d'une action de contrôleur vers une vue? Ou est-ce un modèle trop direct pour le courageux nouveau monde Design Pattern ™ de Magento? S'il s'agit d'un modèle trop direct, que faire s'il y a des informations calculées que nous voulons afficher dans un modèle, mais que nous ne voulons pas stocker ces informations dans un système avec état (c'est-à-dire que nous ne voulons pas les enregistrer dans le base de données)

Je peux penser à quelques façons différentes de pirater cela ensemble moi-même - mais je suis intéressé par la façon dont Magento 2 veut que vous le fassiez.

Remarque : je me rends compte qu'il est possible de récupérer une instance de bloc dans une action de contrôleur en utilisant quelque chose comme ceci

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

var_dump(spl_object_hash($block));

Le code principal de Magento 2 le fait souvent. Cependant - l'objet bloc récupéré dans l'objet contrôleur semble être un objet différent de celui disponible dans un phtmlmodèle via soit $thisou $block(le premier ( $this) semble être l'objet qui rend réellement le modèle, tandis que le dernier ( $block) semble être une instance de type Magento Block).

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

Je dis "semble être" parce que si je définit des données dans la méthode d'action du contrôleur, elles ne sont pas disponibles dans le phtmlmodèle - et si je compare les spl_object_hashrésultats ci-dessus, j'obtiens trois hachages différents. Cependant, je suis assez nouveau pour tout cela que ce qui précède pourrait être une autre erreur que j'ai faite - donc si vous avez pu définir des données sur des blocs et les récupérer dans un modèle, j'aimerais en entendre parler !

Alan Storm
la source

Réponses:

17

Concernant # 1, le registre existe toujours, très similaire à ce que vous savez de Magento 1. Il vient d'être déplacé. Voir:\Magento\Framework\Registry

Ajoutez-le à votre constructeur via l'injection de dépendances, puis vous pouvez utiliser votre familier $registry->register($key, $value)et vos $registry->registry($key)méthodes pour stocker / accéder aux données.

Je recommanderais de fouiller l'espace de noms \ Magento \ Framework si vous ne l'avez pas déjà fait. Une grande partie de ce qui était accessible depuis Mage ou App auparavant est toujours là, juste divisée.

En ce qui concerne les meilleures pratiques, je ne peux pas répondre à cela, mais je m'attends à ce que la réponse soit de garder autant de logique hors du contrôleur que possible. Regarder le cœur est probablement votre meilleur pari. Par exemple, consultez la page de modification de l'adresse client: contrôleur de base ; bloc étendu - y compris l'extraction de l'ID d'adresse et le chargement, si nécessaire. Ils gèrent cela directement dans le bloc; ils ne le font pas dans le contrôleur, puis le font circuler.

Ryan Hoerr
la source
2
L'astuce, bien sûr, est de savoir quelles parties du noyau regarder et lesquelles ignorer :) Merci pour les pointeurs, +1 pour les informations utiles!
Alan Storm
1
+1 pour le dernier paragraphe. Si vous devez partager une valeur calculée, définissez le comportement de calcul sur un objet séparé et appelez-le à partir de blocs qui nécessitent cette valeur. Le registre est déconseillé car il s'agit d'un état mutable global et vous n'êtes jamais sûr de ce que vous obtiendrez à partir de là. L'adressage direct des blocs de l'action est également déconseillé car vous n'êtes jamais sûr si le bloc est présent sur une page (la mise en page peut le tuer)
Anton Kril
@AntonKril que diriez-vous des aides de rendu de page? Assistant de page CMS, assistant de vue produit, sont-ils destinés à séparer le rendu de la demande HTTP?
Ivan Chepurnyi,
5

Vous ne devez pas passer de variables de l'action du contrôleur à la vue. Utilisez le bloc pour passer des variables à afficher (moteur de modèle).

KAndy
la source
Pourquoi? Comment pouvez-vous passer les paramètres get / post du bloc à la vue? La plupart des logiques ne les transmettent-elles pas du contrôleur à l'affichage?
LucScu
Utilisez Request Object en blocs. Si vous bloquez obtenir des données du contrôleur via le Registre, vous ne pouvez pas les utiliser avec d'autres contrôleurs. C'est ce qu'on appelle le couplage temporel et ses mauvaises pratiques
KAndy
J'utilise $ block-> assign () pour passer les paramètres de la requête du contrôleur au bloc. Est-ce aussi une mauvaise pratique?
LucScu
L'adressage direct des blocs de l'action est également déconseillé car vous n'êtes jamais sûr si le bloc est présent sur une page.
KAndy
Dans mon cas, je suis sûr, car c'est un scénario personnalisé où le contrôleur, la disposition et le bloc ne sont contrôlés que par mon code, donc je pense que ce sont les paramètres de la demande de passe logique du contrôleur au bloc. Merci pour vos réponses!
LucScu