Magento 2: Passando variáveis ​​da ação do controlador para “View”

12

No Magento 1, se você deseja passar dados da sua ação do Controller para a "View" (ou seja, um bloco no seu layout, você pode)

  1. Adicione um valor / objeto ao registro global via Mage::register

  2. Buscar diretamente um objeto de bloco e definir propriedades de dados no objeto de bloco buscado após executar loadLayout

  3. Chame métodos em objetos de bloco em phtmlarquivos e faça com que os objetos de bloco usem a camada de modelo / banco de dados para ler dados salvos anteriormente na ação do controlador

O uso de métodos de objeto de bloco para ler no banco de dados ainda parece funcionar no Magento 2 - o que é apropriado para certos tipos de operações. Contudo,

  1. Não há mais um registro global no Magento 2 (ou existe?)

  2. O sistema de layout agora funciona criando um objeto de página através de uma fábrica, e você não pode pegar referências de bloco da mesma maneira que no Magento 1

É possível no Magento 2 passar dados diretamente de uma ação do controlador para uma visualização? Ou isso é um padrão muito direto para o admirável mundo novo Design Pattern ™ do Magento? Se esse é um padrão muito direto, o que deve ser feito se houver alguma informação calculada que desejamos exibir em um modelo, mas não queremos armazenar essas informações em um sistema com estado (por exemplo, não queremos salvá-las no diretório base de dados)

Posso pensar em uma maneira diferente de cortar isso juntos - mas estou interessado em saber como o Magento 2 quer que você faça isso.

Nota : Eu sei que é possível buscar uma instância de bloco em uma ação do controlador usando algo como isto

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

var_dump(spl_object_hash($block));

O código principal do Magento 2 faz isso com frequência. No entanto - o objeto de bloco buscado no objeto do controlador parece ser um objeto diferente do que está disponível em um phtmlmodelo por meio de $thisou $block(o primeiro ( $this) parece ser o objeto que realmente renderiza o modelo, enquanto o último ( $block) parece ser uma instância do tipo Magento Block).

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

Eu digo "parece ser" porque, se eu definir dados no método de ação do controlador, eles não estarão disponíveis no phtmlmodelo - e se eu comparar os spl_object_hashresultados acima, recebo três hashes diferentes. No entanto, sou novo o suficiente para tudo isso, pois o erro acima pode ter sido algum outro erro - por isso, se você conseguiu definir dados em blocos e buscá-los em um modelo que eu adoraria ouvir sobre isso !

Alan Storm
fonte

Respostas:

17

Em relação ao item 1, o registro ainda existe, muito parecido com o que você conhece no Magento 1. Acabou de ser movido. Vejo:\Magento\Framework\Registry

Adicione-o ao seu construtor via injeção de dependência e, em seguida, você poderá usar seus métodos $registry->register($key, $value)e familiares $registry->registry($key)para armazenar / acessar dados.

Eu recomendo dar uma olhada no namespace \ Magento \ Framework, se você ainda não o fez. Muito do que era acessível a partir do Mage ou do App ainda está lá, apenas se separou.

Quanto às melhores práticas, não posso responder a isso, mas espero que a resposta seja manter o máximo de lógica possível fora do controlador. Olhando para o núcleo é provavelmente a sua melhor aposta. Por exemplo, consulte a página de edição do endereço do cliente: Controlador básico ; bloco extenso - incluindo puxar o ID do endereço e carregar, se necessário. Eles lidam com isso diretamente no bloco; eles não fazem isso no controlador e depois passam.

Ryan Hoerr
fonte
2
O truque, é claro, é saber quais partes o núcleo deve examinar e quais ignorar :) Obrigado pelos indicadores, +1 por informações úteis!
Alan Storm
1
+1 no último parágrafo. Se você precisar compartilhar algum valor calculado, coloque o comportamento do cálculo para separar um objeto e chame-o de blocos que requerem esse valor. O registro é desencorajado porque é um estado mutável global e você nunca tem certeza do que obterá a partir daí. Endereçamento direto de blocos de ação também é desencorajado porque você nunca está certo se o bloco está presente em uma página (layout pode matá-lo)
Anton Kril
@AntonKril e os auxiliares do renderizador de páginas? O auxiliar de página do CMS, auxiliar de visualização do produto, serve para separar a renderização da solicitação HTTP?
Ivan Chepurnyi 9/09/2015
5

Você não deve passar variáveis ​​da ação do controlador para a exibição. Use o bloco para passar Variáveis ​​para exibição (mecanismo de modelo).

KAndy
fonte
Por quê? Como você pode passar os parâmetros get / post do bloco para visualizar? A maioria das lógicas não as passa do controlador para a visualização?
LucScu
Use Request Object em blocos. Se você bloquear os dados do controlador por meio do Registro, não poderá usá-los com outros controladores. É chamado de acoplamento Temporal e suas más práticas
Kandy
Eu uso $ block-> assign () para passar os parâmetros do pedido do controlador para o bloco. Também é uma prática ruim?
LucScu
O endereçamento direto de blocos da ação também é desencorajado porque você nunca tem certeza se o bloco está presente em uma página.
Kandy
No meu caso, tenho certeza, porque é um cenário personalizado em que controlador, layout e bloco são controlados apenas pelo meu código, então acho que são os parâmetros de solicitação de passagem lógica do controlador para o bloco. Obrigado por suas respostas!
LucScu