Поскольку мне было трудно найти правильный путь, ниже вы могли найти лучшую практику, которую я сделал своей. Наслаждайтесь, поправьте мой английский, если это необходимо, и скажите, что я ошибаюсь, если это так :)
Изменить: ... и я узнал, что я был неправ в некоторых аспектах. Поэтому я обновил исходный пост после того, как ответы Рафаэля помогли мне понять больше. Спасибо ему !
Концепция используется ниже :
Вам будет легче понять коды и пояснения ниже, если вы знакомы с этими понятиями:
- Зависимость внедрения (поскольку все
$this->variableпеременные в кодах вводятся) - Договор на обслуживание и хранилище
- завод
Контекст :
Просто чтобы иметь больше контекста, представьте, что у нас есть модуль, правильно сконструированный с помощью:
- класс блока CustomBlock, содержащий метод
getCustomModel($id), - этот метод возвращает объект CustomModel на основе идентификатора, переданного в param,
- Тип CustomModel соответствует модели в
\Vendor\Module\Model\CustomModel - Эта модель поставляется с моделью ресурсов (в
\Vendor\Module\Model\ResourceModel\CustomModel) - и с его хранилищем (в
\Vendor\Module\Model\CustomModelRepository).
Вопрос :
- Как лучше всего разрешать загрузку объекта CustomModel?
Вы не можете использовать load()объект из CustomModel, поскольку этот метод устарел.
Хорошая практика говорит о том, что вы должны использовать контракт на обслуживание CustomModel. Сервисные контракты - это интерфейсы данных (например, CustomModelInterface) и сервисные интерфейсы (например, CustomModelRepositoryInterface). Итак, мой блок выглядит так:
/ ** @var SlideRepositoryInterface * /
защищенный $ slideRepository;
/ **
* Конструктор CustomBlock
* ...
* @param CustomModelRepositoryInterface $ customModelRepository
* ...
* /
публичная функция __construct (
...
CustomModelRepositoryInterface $ customModelRepository
...
) {
$ this-> customModelRepository = $ customModelRepository;
}
публичная функция getCustomModel ($ id) {
return $ this-> customModelRepository-> get ($ id);
}
Прежде всего, мы вводим CustomModelRepositoryInterfaceобъект в конструктор и используем его в нашем getCustomModel()методе.
В классе Api\CustomModelRepositoryInterfaceне так много. Как правило (но ничто не мешает вам делать по- другому) вы объявите основные методы: get, getList, save, delete, deleteById. Для целей этого раздела ниже приведено только getобъявление метода:
/**
* Get info by id
*
* @param int $id
* @return Data\CustomModelInterface
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function get($id);
Хорошо, но если мой CustomModel Interface вызывается путем внедрения зависимостей в мой блочный конструктор, где находится код? Для ответа на этот вопрос вы должны объяснить Magento, где найти класс, реализующий этот интерфейс. В файле etc / di.xml модуля вы должны добавить:
<preference for="Vendor\Module\Api\CustomModelRepositoryInterface" type="Vendor\Module\Model\CustomModelRepository" />
Так что CustomModelRepositoryInterfaceкласс - это сервисный интерфейс. При его реализации вам придется реализовать также интерфейсы данных (как минимум, Vendor\Module\Api\Data\CustomModelInterfaceи Vendor\Module\Api\Data\CustomModelSearchResultsInterface). Ваша модель должна будет реализовать Vendor\Module\Api\Data\CustomModelInterfaceи добавить <preference ... />строки для каждого из ваших интерфейсов. Наконец, в любое время, когда вы используете сервисный контракт, не думайте mySomethingInterfaceбольше mySomething: позвольте magento использовать di.xmlмеханизм предпочтений.
Хорошо, что будет дальше? Когда мы внедряем CustomModelRepositoryInterfaceв конструктор блока, мы получаем CustomModelRepositoryобъект. CustomModelRepositoryдолжен реализовать метод объявить в CustomModelRepositoryInterface. Итак, мы имеем это в Vendor\Module\Model\CustomModelRepository:
публичная функция get ($ id) {
$ customModel = $ this-> customModelFactory-> create ();
$ CustomModel-> нагрузка ($ ID);
if (! $ customModel-> getId ()) {
выбросить новое NoSuchEntityException (__ ('CustomModel с идентификатором "% 1" не существует. ", $ id));
}
return $ customModel;
}
Что мы делаем? Мы создаем пустой CustomModelобъект благодаря фабрике. Далее мы загружаем данные с CustomModelиспользованием метода load model. Затем мы возвращаем a, NoSuchEntityExceptionесли нам не удалось загрузить CustomModelидентификатор с параметрами. Но если все в порядке, мы возвращаем модель объекта и жизнь продолжается.
Но вау ... В этом примере что это?
$customModel->load($id);
Разве не такой же устаревший loadметод, как в начале? Да, это так. Я думаю, что это позор, но вы должны использовать его, поскольку в этом методе load () отправляются некоторые события, и разработчик может их прослушать (см. Ответ Рафаэля ниже).
В будущем мы будем сохранять Entity Manager. Это еще одна история, связанная с новой концепцией Magento 2, но если вы захотите взглянуть на нее, Entity Manager уже реализован в Resource Model of CMS Page (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;
}