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->variable
que 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 CustomModelRepositoryInterface
objeto en el constructor y lo usamos en nuestro getCustomModel()
método.
En la clase Api\CustomModelRepositoryInterface
no 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 get
declaració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 CustomModelRepositoryInterface
clase es una interfaz de servicio. Al implementarlo, deberá implementar también interfaces de datos (al menos Vendor\Module\Api\Data\CustomModelInterface
y Vendor\Module\Api\Data\CustomModelSearchResultsInterface
). Su modelo tendrá que implementar Vendor\Module\Api\Data\CustomModelInterface
y agregar <preference ... />
líneas para cada una de sus interfaces. Finalmente, en cualquier momento que use el contrato de servicio, piense en mySomethingInterface
no más en mySomething
: deje que magento use el di.xml
mecanismo de preferencias.
Ok, que viene después? A medida que inyectamos CustomModelRepositoryInterface
en el constructor de bloques, obtenemos un CustomModelRepository
objeto. CustomModelRepository
tiene 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 CustomModel
objeto vacío gracias a la fábrica. A continuación, cargamos datos CustomModel
utilizando el método del modelo de carga. A continuación, devolvemos a NoSuchEntityException
si no pudimos cargar CustomModel
el 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 load
mé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\Observer
carpeta de todos los eventos.fuente