Оскільки мені було важко знайти правильний шлях, нижче ви можете знайти найкращу практику, яку я зробив своєю. Насолоджуйтесь, виправте свою англійську, якщо потрібно, і скажіть, що я помиляюся, якщо є. :)
Редагувати: ... і я дізнався, що я помилявся з якогось аспекту. Тож я оновив оригінальний пост після того, як відповіді Рафаеля допомогли мені зрозуміти більше. Дякую йому!
Поняття, що використовується нижче :
Вам буде простіше зрозуміти коди та пояснення нижче, якщо вам подобаються ці поняття:
- Залежність від ін'єкції (як і всі
$this->variable
змінні в коди вводяться) - Контракт на обслуговування та сховище
- Заводська
Контекст :
Просто, щоб мати більше контексту, уявіть, що у нас правильно побудований модуль:
- блок-клас CustomBlock, що містить метод
getCustomModel($id)
, - цей метод повертає об’єкт CustomModel на основі ідентифікатора, переданого в парамі,
- Тип 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) { повернути $ 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 викликається введенням залежності в мій конструктор блоків, де код? Щоб відповісти на це питання, ви повинні пояснити 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
: нехай магенто використовує di.xml
механізм налаштувань.
Гаразд, що далі? Коли ми вводимо CustomModelRepositoryInterface
в конструктор блоків, ми отримуємо CustomModelRepository
об'єкт. CustomModelRepository
має реалізувати метод, оголошений в CustomModelRepositoryInterface
. Отже, ми маємо це у Vendor\Module\Model\CustomModelRepository
:
Отримати публічну функцію ($ id) { $ customModel = $ this-> customModelFactory-> create (); $ customModel-> завантаження ($ id); if (! $ customModel-> getId ()) { кинути новий NoSuchEntityException (__ ('CustomModel з ідентифікатором "% 1" не існує. ", $ id)); } повернути $ customModel; }
Що ми робимо? Ми створюємо порожній CustomModel
об’єкт завдяки фабриці. Далі ми завантажуємо дані за CustomModel
допомогою методу моделі навантаження. Далі ми повертаємо a, NoSuchEntityException
якщо нам не вдалося завантажити CustomModel
ідентифікатор у парамах. Але якщо все в порядку, ми повертаємо модельний об’єкт і життя продовжується.
Але вау ...! У цьому прикладі що це?
$customModel->load($id);
Це не той самий застарілий load
метод, як на початку? Так. Я думаю, що це шкода, але вам доведеться використовувати його, оскільки в цьому методі load () є деякі події, що розсилаються, і розробник може їх слухати (див. Відповідь Рафаеля нижче).
Надалі нас врятує Entity Manager. Це вже інша історія, як нова концепція Magento 2, але якщо ви хочете зазирнути, Entity Manager вже реалізований у Моделі ресурсів Сторінки 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;
}