Поскольку мне было трудно найти правильный путь, ниже вы могли найти лучшую практику, которую я сделал своей. Наслаждайтесь, поправьте мой английский, если это необходимо, и скажите, что я ошибаюсь, если это так :)
Изменить: ... и я узнал, что я был неправ в некоторых аспектах. Поэтому я обновил исходный пост после того, как ответы Рафаэля помогли мне понять больше. Спасибо ему !
Концепция используется ниже :
Вам будет легче понять коды и пояснения ниже, если вы знакомы с этими понятиями:
- Зависимость внедрения (поскольку все
$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;
}
источник
load()
. Модель ресурсов вызывает методы модели из собственногоload()
метода:$model->beforeLoad() { $this->_beforeLoad() }
и$model->afterLoad() { $this->_afterLoad() }
Я думаю, что следующее утверждение не является действительным сейчас.
мы можем найти
Magento\Framework\EntityManager\Observer
папку все события.источник