Da es mir schwerfiel, den richtigen Weg zu finden, konnten Sie unten die besten Methoden finden, die ich für mich entwickelt habe. Genießen Sie, korrigieren Sie mein Englisch, wenn nötig, und sagen Sie mir, dass ich mich irre, wenn ich es bin. :)
Edit: ... und ich fand heraus, dass ich in einem Aspekt falsch lag. Also habe ich den ursprünglichen Beitrag aktualisiert, nachdem Raphaels Antworten mir geholfen haben, mehr zu verstehen. Dank ihm !
Das unten verwendete Konzept :
Wenn Sie mit diesen Konzepten vertraut sind, ist es für Sie einfacher, die folgenden Codes und Erklärungen zu verstehen:
- Injektionsabhängigkeit (da alle
$this->variable
Variablen in Codes injiziert werden) - Servicevertrag und Repository
- Fabrik
Kontext :
Um mehr Kontext zu haben, stellen Sie sich vor, wir haben ein Modul, das richtig konstruiert ist mit:
- eine Blockklasse CustomBlock, die eine Methode enthält
getCustomModel($id)
, - Diese Methode gibt ein CustomModel-Objekt zurück, das auf der in param übergebenen ID basiert.
- Der CustomModel-Typ entspricht dem Modell in
\Vendor\Module\Model\CustomModel
- Dieses Modell wird mit seinem Ressourcenmodell (in
\Vendor\Module\Model\ResourceModel\CustomModel
) geliefert. - und mit seinem Repository (in
\Vendor\Module\Model\CustomModelRepository
).
Frage :
- Was ist die beste Methode, um ein CustomModel-Objekt vollständig laden zu lassen?
Sie können das load()
von einem CustomModel-Objekt nicht verwenden, da diese Methode veraltet ist.
Nach der guten Praxis müssen Sie den CustomModel-Servicevertrag verwenden. Serviceverträge sind Datenschnittstellen (zB CustomModelInterface) und Serviceschnittstellen (zB CustomModelRepositoryInterface). Mein Block sieht also so aus:
/ ** @var SlideRepositoryInterface * / protected $ slideRepository; / ** * CustomBlock-Konstruktor * ... * @param CustomModelRepositoryInterface $ customModelRepository * ... * / public function __construct ( ... CustomModelRepositoryInterface $ customModelRepository ... ) { $ this-> customModelRepository = $ customModelRepository; } öffentliche Funktion getCustomModel ($ id) { return $ this-> customModelRepository-> get ($ id); }
Zunächst injizieren wir das CustomModelRepositoryInterface
Objekt in den Konstruktor und verwenden es in unserer getCustomModel()
Methode.
In der Klasse Api\CustomModelRepositoryInterface
gibt es nicht viel. Im Allgemeinen (aber nichts verhindern , dass Sie anders machen) finden Sie grundlegende Methoden erklären: get
, getList
, save
, delete
, deleteById
. Für den Zweck dieses Themas ist im Folgenden nur die get
Methodendeklaration aufgeführt:
/**
* Get info by id
*
* @param int $id
* @return Data\CustomModelInterface
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function get($id);
Ok, aber wenn mein CustomModel-Interface durch Abhängigkeitsinjektion in meinem Blockkonstruktor aufgerufen wird, wo ist der Code? Um diese Frage zu beantworten, müssen Sie Magento erklären, wo sich die Klasse befindet, die diese Schnittstelle implementiert. In der etc / di.xml-Datei des Moduls müssen Sie Folgendes hinzufügen:
<preference for="Vendor\Module\Api\CustomModelRepositoryInterface" type="Vendor\Module\Model\CustomModelRepository" />
So CustomModelRepositoryInterface
Klasse ist eine Service - Schnittstelle. Bei der Implementierung müssen Sie (mindestens Vendor\Module\Api\Data\CustomModelInterface
und Vendor\Module\Api\Data\CustomModelSearchResultsInterface
) auch Datenschnittstellen implementieren . Ihr Modell muss Zeilen für jede Ihrer Schnittstellen implementieren Vendor\Module\Api\Data\CustomModelInterface
und hinzufügen <preference ... />
. Zu jedem Zeitpunkt, an dem Sie den Servicevertrag nutzen, sollten Sie mySomethingInterface
nicht mehr daran denken mySomething
: Lassen Sie Magento den Voreinstellungsmechanismus nutzen di.xml
.
Ok was kommt als nächstes Wenn wir CustomModelRepositoryInterface
den Blockkonstruktor einfügen, erhalten wir ein CustomModelRepository
Objekt. CustomModelRepository
muss die Methode declare in implementieren CustomModelRepositoryInterface
. Das haben wir also in Vendor\Module\Model\CustomModelRepository
:
public function get ($ id) { $ customModel = $ this-> customModelFactory-> create (); $ customModel-> load ($ id); if (! $ customModel-> getId ()) { Neue NoSuchEntityException auslösen (__ ('CustomModel mit der ID "% 1" existiert nicht.', $ id)); } return $ customModel; }
Was machst du ? CustomModel
Dank der Fabrik schaffen wir ein leeres Objekt. Als nächstes laden wir Daten CustomModel
mit der Lademodellmethode. Als nächstes geben wir ein zurück, NoSuchEntityException
wenn wir das nicht CustomModel
mit der ID in params laden konnten. Aber wenn alles in Ordnung ist, geben wir das Modellobjekt zurück und das Leben geht weiter.
Aber wow ...! In diesem Beispiel, was ist das?
$customModel->load($id);
Ist das nicht dieselbe veraltete load
Methode wie zu Beginn? Ja ist es. Ich denke, es ist eine Schande, aber Sie müssen es verwenden, da in dieser load () -Methode einige Ereignisse ausgelöst werden und der Entwickler auf sie warten kann (siehe Raphaels Antwort unten).
In Zukunft werden wir von Entity Manager gespeichert. Es ist eine andere Geschichte als ein neues Magento 2-Konzept, aber wenn Sie einen Blick darauf werfen möchten, ist Entity Manager bereits im Ressourcenmodell von CMS Page (v2.1) implementiert:
public function load(AbstractModel $object, $value, $field = null)
{
$pageId = $this->getPageId($object, $value, $field);
if ($pageId) {
$this->entityManager->load($object, $pageId);
}
return $this;
}