Debido a que fue difícil para mí encontrar el camino correcto, a continuación podría encontrar la mejor práctica que hice para mí. Disfruta, corrige mi inglés si es necesario y dime que estoy equivocado si lo estoy. :)
Editar: ... y descubrí que estaba equivocado en algún aspecto. Así que actualicé la publicación original después de que las respuestas de Raphael me ayudaron a entender más. Gracias a él !
Concepto utilizado a continuación :
Le resultará más fácil comprender los códigos y explicaciones a continuación si se siente cómodo con estos conceptos:
- Dependencia de inyección (ya
$this->variableque se inyectan todas las variables en los códigos) - Contrato de servicio y repositorio
- Fábrica
Contexto :
Solo para tener más contexto, imagine que tenemos un módulo construido correctamente con:
- una clase de bloque CustomBlock que contiene un método
getCustomModel($id), - este método devuelve un objeto CustomModel basado en la identificación pasada en param,
- El tipo de modelo personalizado corresponde al modelo en
\Vendor\Module\Model\CustomModel - Este modelo viene con su modelo de recurso (en
\Vendor\Module\Model\ResourceModel\CustomModel) - y con su repositorio (en
\Vendor\Module\Model\CustomModelRepository).
Pregunta :
- ¿Cuál es la mejor práctica para dejar que todo cargue un objeto CustomModel?
No puede usar load()desde un objeto CustomModel ya que este método está en desuso.
La buena práctica dice que debe usar el contrato de servicio CustomModel. Los contratos de servicio son interfaces de datos (por ejemplo, CustomModelInterface) e interfaces de servicio (por ejemplo, CustomModelRepositoryInterface). Entonces mi bloque se ve así:
/ ** @var SlideRepositoryInterface * /
protegido $ slideRepository;
/ **
* Constructor CustomBlock
* ...
* @param CustomModelRepositoryInterface $ customModelRepository
* ...
* /
función pública __construct (
...
CustomModelRepositoryInterface $ customModelRepository
...
) {
$ this-> customModelRepository = $ customModelRepository;
}
función pública getCustomModel ($ id) {
devuelve $ this-> customModelRepository-> get ($ id);
}
En primer lugar, inyectamos el CustomModelRepositoryInterfaceobjeto en el constructor y lo usamos en nuestro getCustomModel()método.
En la clase Api\CustomModelRepositoryInterfaceno hay mucho. Por lo general (pero nada impide que usted pueda hacer de manera diferente) que se declare métodos básicos: get, getList, save, delete, deleteById. A los efectos de este tema, a continuación se muestra solo la getdeclaración del método:
/**
* Get info by id
*
* @param int $id
* @return Data\CustomModelInterface
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function get($id);
Ok, pero si mi interfaz CustomModel se llama por inyección de dependencia en mi constructor de bloques, ¿dónde está el código? Para responder a esta pregunta, debe explicarle a Magento dónde encontrar la clase que implementa esta interfaz. En el archivo etc / di.xml del módulo, debe agregar:
<preference for="Vendor\Module\Api\CustomModelRepositoryInterface" type="Vendor\Module\Model\CustomModelRepository" />
Entonces CustomModelRepositoryInterfaceclase es una interfaz de servicio. Al implementarlo, deberá implementar también interfaces de datos (al menos Vendor\Module\Api\Data\CustomModelInterfacey Vendor\Module\Api\Data\CustomModelSearchResultsInterface). Su modelo tendrá que implementar Vendor\Module\Api\Data\CustomModelInterfacey agregar <preference ... />líneas para cada una de sus interfaces. Finalmente, en cualquier momento que use el contrato de servicio, piense en mySomethingInterfaceno más en mySomething: deje que magento use el di.xmlmecanismo de preferencias.
Ok, que viene después? A medida que inyectamos CustomModelRepositoryInterfaceen el constructor de bloques, obtenemos un CustomModelRepositoryobjeto. CustomModelRepositorytiene que implementar el método declarar en CustomModelRepositoryInterface. Entonces tenemos esto en Vendor\Module\Model\CustomModelRepository:
función pública get ($ id) {
$ customModel = $ this-> customModelFactory-> create ();
$ customModel-> load ($ id);
if (! $ customModel-> getId ()) {
lanzar una nueva NoSuchEntityException (__ ('CustomModel con id "% 1" no existe.', $ id));
}
return $ customModel;
}
Qué estamos haciendo ? Creamos un CustomModelobjeto vacío gracias a la fábrica. A continuación, cargamos datos CustomModelutilizando el método del modelo de carga. A continuación, devolvemos a NoSuchEntityExceptionsi no pudimos cargar CustomModelel id con los parámetros. Pero si todo está bien, devolvemos el objeto modelo y la vida continúa.
Pero wow ...! En este ejemplo, ¿qué es eso?
$customModel->load($id);
¿No es el mismo loadmétodo obsoleto que al principio? Sí lo es. Creo que es una pena, pero debe usarlo ya que en este método load () hay algunos eventos enviados y el desarrollador podría escucharlos (vea la respuesta de Raphael a continuación).
En el futuro, seremos salvados por Entity Manager. Es otra historia como un nuevo concepto de Magento 2, pero si desea echar un vistazo, Entity Manager ya está implementado en el Modelo de recursos de la 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;
}
fuente

load()método del modelo de recurso Resource Model llama a los métodos del modelo desde su propioload()método:$model->beforeLoad() { $this->_beforeLoad() }y$model->afterLoad() { $this->_afterLoad() }Creo que la siguiente declaración no es válida ahora.
Podemos encontrar la
Magento\Framework\EntityManager\Observercarpeta de todos los eventos.fuente