Perché è stato difficile per me trovare la strada giusta, di seguito puoi trovare la migliore pratica che ho fatto mio. Divertiti, correggi il mio inglese se necessario e dimmi che sbaglio se lo sono. :)
Modifica: ... e ho scoperto che mi sbagliavo su alcuni aspetti. Così ho aggiornato il post originale dopo che le risposte di Raffaello mi hanno aiutato a capire di più. Grazie a lui !
Concetto utilizzato di seguito :
Sarà più facile per te comprendere i codici e le spiegazioni di seguito se ti senti a tuo agio con questi concetti:
- Dipendenza da iniezione (poiché
$this->variable
vengono iniettate tutte le variabili nei codici) - Contratto di servizio e deposito
- Fabbrica
Contesto :
Giusto per avere più contesto, immagina di avere un modulo correttamente costruito con:
- una classe di blocco CustomBlock contenente un metodo
getCustomModel($id)
, - questo metodo restituisce un oggetto CustomModel basato sull'id passato in param,
- Il tipo CustomModel corrisponde al modello in
\Vendor\Module\Model\CustomModel
- Questo modello viene fornito con il suo modello di risorsa (in
\Vendor\Module\Model\ResourceModel\CustomModel
) - e con il suo repository (in
\Vendor\Module\Model\CustomModelRepository
).
Domanda :
- Qual è la migliore pratica per consentire a tutto il caricamento di un oggetto CustomModel?
Non è possibile utilizzare l' load()
oggetto da un oggetto CustomModel poiché questo metodo è obsoleto.
La buona pratica afferma che è necessario utilizzare il contratto di assistenza CustomModel. I contratti di assistenza sono interfacce dati (ad es. CustomModelInterface) e interfacce di servizio (ad es. CustomModelRepositoryInterface). Quindi il mio blocco è simile al seguente:
/ ** @var SlideRepositoryInterface * / protetto $ slideRepository; / ** * Costruttore CustomBlock * ... * @param CustomModelRepositoryInterface $ customModelRepository * ... * / funzione pubblica __construct ( ... CustomModelRepositoryInterface $ customModelRepository ... ) { $ this-> customModelRepository = $ customModelRepository; } funzione pubblica getCustomModel ($ id) { return $ this-> customModelRepository-> get ($ id); }
Prima di tutto, iniettiamo l' CustomModelRepositoryInterface
oggetto nel costruttore e lo usiamo nel nostro getCustomModel()
metodo.
In classe Api\CustomModelRepositoryInterface
non c'è molto. In generale (ma nulla impedisce di fare diversamente) si dichiara metodi di base: get
, getList
, save
, delete
, deleteById
. Ai fini di questo argomento, di seguito è riportata solo la get
dichiarazione del metodo:
/**
* Get info by id
*
* @param int $id
* @return Data\CustomModelInterface
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function get($id);
Ok, ma se la mia interfaccia CustomModel viene chiamata dall'iniezione di dipendenza nel mio costruttore di blocchi, dov'è il codice? Per rispondere a questa domanda devi spiegare a Magento dove trovare la classe che implementa questa interfaccia. Nel file etc / di.xml del modulo, devi aggiungere:
<preference for="Vendor\Module\Api\CustomModelRepositoryInterface" type="Vendor\Module\Model\CustomModelRepository" />
Quindi la CustomModelRepositoryInterface
classe è un'interfaccia di servizio. Nella sua attuazione dovrai implementare anche le interfacce dati (almeno Vendor\Module\Api\Data\CustomModelInterface
e Vendor\Module\Api\Data\CustomModelSearchResultsInterface
). Il tuo modello dovrà implementare Vendor\Module\Api\Data\CustomModelInterface
e aggiungere <preference ... />
linee per ciascuna delle tue interfacce. Infine, in qualsiasi momento utilizzi il contratto di assistenza, non pensare mySomethingInterface
più a mySomething
: lascia che magento usi il di.xml
meccanismo delle preferenze.
Ok, cosa viene dopo? Quando iniettiamo CustomModelRepositoryInterface
nel costruttore di blocchi, otteniamo un CustomModelRepository
oggetto. CustomModelRepository
deve implementare il metodo dichiarare in CustomModelRepositoryInterface
. Quindi abbiamo questo in Vendor\Module\Model\CustomModelRepository
:
funzione pubblica get ($ id) { $ customModel = $ this-> customModelFactory-> create (); $ CustomModel-> load ($ id); if (! $ customModel-> getId ()) { lancia new NoSuchEntityException (__ ('CustomModel con ID "% 1" non esiste.', $ id)); } return $ customModel; }
Cosa stiamo facendo ? Creiamo un CustomModel
oggetto vuoto grazie alla fabbrica. Successivamente cariciamo i dati CustomModel
utilizzando il metodo del modello di caricamento. Quindi restituiamo a NoSuchEntityException
se non siamo riusciti a caricare CustomModel
l'ID con i parametri. Ma se tutto va bene, restituiamo l'oggetto modello e la vita continua.
Ma wow ...! In questo esempio che cos'è?
$customModel->load($id);
Lo stesso load
metodo deprecato non è all'inizio? Sì. Penso che sia un peccato, ma devi usarlo poiché in questo metodo load () ci sono alcuni eventi inviati e lo sviluppatore potrebbe ascoltarli (vedi la risposta di Raphael sotto).
In futuro, saremo salvati da Entity Manager. È un'altra storia come un nuovo concetto di Magento 2, ma se vuoi dare un'occhiata, Entity Manager è già implementato nel modello di risorsa della pagina 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;
}