Templates Magento 2: Use `$ block` ou` $ this`?

27

No Magento 2, a $thisvariável não se refere mais ao objeto de bloco de um modelo. Refere-se a uma classe de modelo

 Magento\Framework\View\TemplateEngine\Php

No entanto, essa classe de modelo possui um __callmétodo de passagem

#File: vendor/magento/framework/View/TemplateEngine/Php.php
public function __call($method, $args)
{
    return call_user_func_array([$this->_currentBlock, $method], $args);
}

O que garante que qualquer chamada de método chegue ao bloco real. Isso também explica por que você não pode chamar métodos protegidos de phtmlmodelos.

Além disso, todo modelo (eu acho?) Tem uma variável denominada $blockpreenchida, que também se refere ao objeto de bloco pai. Você pode ver isso em uso no modelo de lista do Magento

#File: vendor/magento/module-catalog/view/frontend/templates/product/list.phtml
//...
$_productCollection = $block->getLoadedProductCollection();

onde a $blockvariável é usada, mas nunca definida explicitamente.

Além das diferenças mencionadas acima, existe alguma diferença entre usar uma técnica sobre a outra? ie Faça os dois $blocke se $this->currentBlockrefira ao mesmo objeto?

Alan Storm
fonte

Respostas:

32

Em um arquivo de modelo, $blocke $this->_currentBlocksão a mesma coisa.

Dê uma olhada no rendermétodo no Php.phpmecanismo de modelo.
Antes de incluir o arquivo de modelo, isso acontece: $this->_currentBlock = $block;o arquivo de modelo é incluído usando um simples include $fileName;.
Isso significa que dentro de um modelo você ainda está dentro do Phpmecanismo de modelo. É por isso que $thisfunciona, e é por isso que $blocké definido.

[EDIT]
Acabei de descobrir que o uso de $thismodelos internos é desencorajado.
O php sniffer com os padrões EcgM2 mostra um aviso ao usar $thismodelos internos.
Substituir $thispor $blockfaz o aviso desaparecer.

Marius
fonte
Então, qual é o objeto padrão no arquivo .phtml $ block ou $ this.
Manish Goswami
O que você quer dizer com padrão?
Marius
Qual é a variável padrão usada em um modelo para acessar a classe de renderização do modelo? Existe alguma diferença entre esses dois para acessar a função?
Manish Goswami
Diz em qualquer resposta. Ambos funcionam, mas é recomendado o uso$block
Marius
5

Até onde eu vi, ambos são quase os mesmos no PHP TemplateEngineInterface, mas lembre-se de que no Magento2 você pode criar mecanismos de modelos personalizados. Não é como o Magento1, no qual você tinha apenas arquivos phtml.

Se você vir o, TemplateEngineInterfacenão poderá ver nenhuma referência a nenhum método que chame o currentBlock, então acho que a $this->currentBlockabordagem é específica do modelo PHP.

Mas, para ser independente do mecanismo do modelo, $blockdeve ser a abordagem correta.

Quero dizer que, do ponto de vista teórico, você poderia criar um mecanismo diferente baseado em PHP que não pudesse confiar em arquivos phtml, mas talvez em alguma outra estrutura PHP.

Eu assumo $blockcomo o caminho "certo" para o modo "phtml" porque é explicitamente passado como variável de contexto.

$blocke $this->currentBlocksão os mesmos do ponto de vista técnico, mas se eles explicitamente usaram $block, acho que deveríamos usá-lo, do ponto de vista do estilo do código.

Phoenix128_RiccardoT
fonte
Mas nem o bloco $ faz parte da interface. Eu diria que é seguro supor que essa implementação seja usada quando você estiver dentro de um arquivo phtml. Outras implementações não usarão o arquivo phtml.
Fabian Schmengler
Você está certo, não tenho sido claro na minha resposta para explicar o que quero dizer. Modifiquei minha postagem com mais detalhes.
Phoenix128_RiccardoT