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->variablevengono 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' CustomModelRepositoryInterfaceoggetto nel costruttore e lo usiamo nel nostro getCustomModel()metodo.
In classe Api\CustomModelRepositoryInterfacenon 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 getdichiarazione 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 CustomModelRepositoryInterfaceclasse è un'interfaccia di servizio. Nella sua attuazione dovrai implementare anche le interfacce dati (almeno Vendor\Module\Api\Data\CustomModelInterfacee Vendor\Module\Api\Data\CustomModelSearchResultsInterface). Il tuo modello dovrà implementare Vendor\Module\Api\Data\CustomModelInterfacee aggiungere <preference ... />linee per ciascuna delle tue interfacce. Infine, in qualsiasi momento utilizzi il contratto di assistenza, non pensare mySomethingInterfacepiù a mySomething: lascia che magento usi il di.xmlmeccanismo delle preferenze.
Ok, cosa viene dopo? Quando iniettiamo CustomModelRepositoryInterfacenel costruttore di blocchi, otteniamo un CustomModelRepositoryoggetto. CustomModelRepositorydeve 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 CustomModeloggetto vuoto grazie alla fabbrica. Successivamente cariciamo i dati CustomModelutilizzando il metodo del modello di caricamento. Quindi restituiamo a NoSuchEntityExceptionse non siamo riusciti a caricare CustomModell'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 loadmetodo 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;
}