Como era difícil para mim encontrar o caminho certo, abaixo você encontrava a melhor prática que fiz. Aproveite, corrija meu inglês, se necessário, e diga que estou errado, se estiver. :)
Edit: ... e eu descobri que estava errado em algum aspecto. Atualizei o post original depois que as respostas de Raphael me ajudaram a entender mais. Graças a ele !
Conceito usado abaixo :
Será mais fácil para você entender códigos e explicações abaixo se estiver familiarizado com estes conceitos:
- Dependência de injeção (como todas as
$this->variable
variáveis nos códigos são injetadas) - Contrato de Serviço e Repositório
- Fábrica
Contexto :
Apenas para ter mais contexto, imagine que temos um módulo construído corretamente com:
- uma classe de bloco CustomBlock contendo um método
getCustomModel($id)
, - esse método retorna um objeto CustomModel com base no ID passado em param,
- O tipo CustomModel corresponde ao modelo em
\Vendor\Module\Model\CustomModel
- Este modelo vem com seu modelo de recursos (in
\Vendor\Module\Model\ResourceModel\CustomModel
) - e com seu repositório (in
\Vendor\Module\Model\CustomModelRepository
).
Pergunta :
- Qual é a melhor prática para permitir que tudo carregue um objeto CustomModel?
Você não pode usar o load()
objeto de CustomModel, pois esse método está obsoleto.
A boa prática diz que você precisa usar o contrato de serviço CustomModel. Os contratos de serviço são interfaces de dados (por exemplo, CustomModelInterface) e interfaces de serviço (por exemplo, CustomModelRepositoryInterface). Então, meu bloco fica assim:
/ ** @var SlideRepositoryInterface * / protegido $ slideRepository; / ** * Construtor CustomBlock * ... * @param CustomModelRepositoryInterface $ customModelRepository * ... * / função pública __construct ( ... CustomModelRepositoryInterface $ customModelRepository ... ) { $ this-> customModelRepository = $ customModelRepository; } função pública getCustomModel ($ id) { retornar $ this-> customModelRepository-> get ($ id); }
Primeiro, injetamos o CustomModelRepositoryInterface
objeto no construtor e o usamos em nosso getCustomModel()
método.
Na classe Api\CustomModelRepositoryInterface
não há muito. Geralmente (mas nada impedi-lo de fazer diferente), você irá declarar métodos básicos: get
, getList
, save
, delete
, deleteById
. Para os fins deste tópico, abaixo está apenas a get
declaração do método:
/**
* Get info by id
*
* @param int $id
* @return Data\CustomModelInterface
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function get($id);
Ok, mas se minha interface CustomModel é chamada por injeção de dependência no meu construtor de blocos, onde está o código? Para responder a esta pergunta, você precisa explicar ao Magento onde encontra a classe que implementa essa interface. No arquivo etc / di.xml do módulo, você deve adicionar:
<preference for="Vendor\Module\Api\CustomModelRepositoryInterface" type="Vendor\Module\Model\CustomModelRepository" />
Então CustomModelRepositoryInterface
classe é uma interface de serviço. Ao implementá-lo, você precisará implementar também interfaces de dados (pelo menos Vendor\Module\Api\Data\CustomModelInterface
e Vendor\Module\Api\Data\CustomModelSearchResultsInterface
). Seu modelo precisará implementar Vendor\Module\Api\Data\CustomModelInterface
e adicionar <preference ... />
linhas para cada uma de suas interfaces. Finalmente, sempre que você usar um contrato de serviço, mySomethingInterface
não pense mais em mySomething
: deixe o magento usar o di.xml
mecanismo de preferências.
Ok, o que vem a seguir? Quando injetamos CustomModelRepositoryInterface
no construtor do bloco, obtemos um CustomModelRepository
objeto. CustomModelRepository
deve implementar o método declare in CustomModelRepositoryInterface
. Então, temos isso em Vendor\Module\Model\CustomModelRepository
:
função pública get ($ id) { $ customModel = $ this-> customModelFactory-> create (); $ customModel-> load ($ id); if (! $ customModel-> getId ()) { lança nova NoSuchEntityException (__ ('CustomModel com o ID "% 1" não existe.', $ id)); } return $ customModel; }
O que estamos fazendo ? Criamos um CustomModel
objeto vazio graças à fábrica. Em seguida, carregamos dados no CustomModel
método usando o modelo de carregamento. Em seguida, retornamos a NoSuchEntityException
se não conseguimos carregar o CustomModel
com o id nos parâmetros. Mas se estiver tudo bem, retornamos o objeto modelo e a vida continua.
Mas uau ...! Neste exemplo, o que é isso?
$customModel->load($id);
Não é o mesmo load
método obsoleto do que no começo? Sim, ele é. Acho uma pena, mas você deve usá-lo, pois neste método load () existem alguns eventos despachados e o desenvolvedor pode ouvi-los (consulte a resposta de Raphael abaixo).
No futuro, seremos salvos pelo Entity Manager. É outra história como um novo conceito Magento 2, mas se você quiser dar uma olhada, o Entity Manager já está implementado no Modelo de Recursos da Página CMS (v2.1):
public function load(AbstractModel $object, $value, $field = null)
{
$pageId = $this->getPageId($object, $value, $field);
if ($pageId) {
$this->entityManager->load($object, $pageId);
}
return $this;
}
fonte
load()
método do Modelo de Recurso . Modelo de Recursos chama métodos do modelo de próprioload()
método:$model->beforeLoad() { $this->_beforeLoad() }
e$model->afterLoad() { $this->_afterLoad() }
Eu acho que a seguinte declaração não é válida agora.
podemos encontrar
Magento\Framework\EntityManager\Observer
pasta todos os eventos.fonte