Bởi vì thật khó để tôi tìm đúng cách, dưới đây bạn có thể tìm thấy cách thực hành tốt nhất mà tôi đã thực hiện. Hãy tận hưởng, sửa tiếng Anh của tôi nếu cần và nói tôi sai nếu tôi là. :)
Chỉnh sửa: ... và tôi phát hiện ra mình đã sai ở một khía cạnh nào đó. Vì vậy, tôi đã cập nhật bài viết gốc sau khi câu trả lời của Raphael giúp tôi hiểu thêm. Cảm ơn anh!
Khái niệm được sử dụng dưới đây :
Sẽ dễ dàng hơn cho bạn để hiểu các mã và giải thích bên dưới nếu bạn cảm thấy thoải mái với các khái niệm này:
- Phụ thuộc tiêm (như mọi
$this->variable
biến trong mã được tiêm) - Hợp đồng dịch vụ và kho lưu trữ
- Nhà máy
Bối cảnh :
Để có thêm ngữ cảnh, hãy tưởng tượng chúng ta có một mô-đun xây dựng chính xác với:
- một lớp CustomBlock chứa một phương thức
getCustomModel($id)
, - phương thức này trả về một đối tượng CustomModel dựa trên id được truyền trong param,
- Loại CustomModel tương ứng với mô hình trong
\Vendor\Module\Model\CustomModel
- Mô hình này đi kèm với mô hình tài nguyên của nó (trong
\Vendor\Module\Model\ResourceModel\CustomModel
) - và với kho lưu trữ của nó (trong
\Vendor\Module\Model\CustomModelRepository
).
Câu hỏi :
- Cách tốt nhất để cho tất cả mọi thứ tải một đối tượng CustomModel là gì?
Bạn không thể sử dụng load()
từ một đối tượng CustomModel vì phương thức này không được dùng nữa.
Thực tiễn tốt nói rằng bạn phải sử dụng Hợp đồng dịch vụ CustomModel. Hợp đồng dịch vụ là giao diện dữ liệu (ví dụ: CustomModelInterface) và giao diện dịch vụ (ví dụ: CustomModelRep repositoryInterface). Vì vậy, khối của tôi trông như thế này:
/ ** @var SlideRep repositoryInterface * / được bảo vệ $ slideRep repository; / ** * Trình xây dựng CustomBlock * ... * @param CustomModelRep repositoryInterface $ customModelRep repository * ... * / chức năng công cộng __construct ( ... CustomModelRep repositoryInterface $ customModelRep repository ... ) { $ this-> customModelRep repository = $ customModelRep repository; } chức năng công khai getCustomModel ($ id) { trả về $ this-> customModelRep repository-> get ($ id); }
Trước hết, chúng ta tiêm CustomModelRepositoryInterface
đối tượng vào hàm tạo và chúng ta sử dụng nó trong getCustomModel()
phương thức của chúng ta .
Trong lớp Api\CustomModelRepositoryInterface
không có nhiều. Nói chung (nhưng không có gì ngăn cản bạn làm cách khác nhau), bạn sẽ tuyên bố phương pháp cơ bản: get
, getList
, save
, delete
, deleteById
. Vì mục đích của chủ đề này, dưới đây chỉ là get
phương pháp kê khai:
/**
* Get info by id
*
* @param int $id
* @return Data\CustomModelInterface
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function get($id);
Ok, nhưng nếu Giao diện CustomModel của tôi được gọi bằng cách tiêm phụ thuộc trong hàm tạo khối của tôi, thì mã ở đâu? Để trả lời cho câu hỏi này, bạn phải giải thích cho Magento nơi tìm lớp thực hiện giao diện này. Trong tệp etc / di.xml của mô-đun, bạn phải thêm:
<preference for="Vendor\Module\Api\CustomModelRepositoryInterface" type="Vendor\Module\Model\CustomModelRepository" />
Vì vậy, CustomModelRepositoryInterface
lớp là một giao diện dịch vụ. Khi thực hiện nó, bạn sẽ phải thực hiện cả giao diện dữ liệu (ít nhất là Vendor\Module\Api\Data\CustomModelInterface
và Vendor\Module\Api\Data\CustomModelSearchResultsInterface
). Mô hình của bạn sẽ phải thực hiện Vendor\Module\Api\Data\CustomModelInterface
và thêm <preference ... />
các dòng cho mỗi một giao diện của bạn. Cuối cùng, bất cứ lúc nào bạn sử dụng hợp đồng dịch vụ, hãy suy nghĩ mySomethingInterface
không nữa mySomething
: hãy để magento sử dụng di.xml
cơ chế ưu tiên.
Ok, điều gì đến tiếp theo? Khi chúng ta tiêm CustomModelRepositoryInterface
vào hàm tạo khối, chúng ta sẽ có một CustomModelRepository
đối tượng. CustomModelRepository
phải thực hiện phương thức khai báo trong CustomModelRepositoryInterface
. Vì vậy, chúng tôi có điều này trong Vendor\Module\Model\CustomModelRepository
:
chức năng công khai get ($ id) { $ customModel = $ this-> customModelFactory-> create (); $ customModel-> tải ($ id); if (! $ customModel-> getId ()) { ném NoSuchEntityException mới (__ ('CustomModel với id "% 1" không tồn tại.', $ id)); } trả về $ customModel; }
Chúng ta đang làm gì? Chúng tôi tạo ra một CustomModel
đối tượng trống nhờ vào nhà máy. Tiếp theo chúng ta tải dữ liệu theo CustomModel
phương pháp mô hình tải. Tiếp theo, chúng tôi trả về NoSuchEntityException
nếu chúng tôi không tải CustomModel
được id trong params. Nhưng nếu mọi thứ đều ổn, chúng tôi trả lại đối tượng mô hình và cuộc sống vẫn tiếp tục.
Nhưng wow ...! Trong ví dụ này đó là gì?
$customModel->load($id);
Không phải là load
phương pháp không dùng nữa so với lúc ban đầu sao? Vâng, đúng vậy. Tôi nghĩ đó là một sự xấu hổ, nhưng bạn phải sử dụng nó vì trong phương thức load () này có một số sự kiện được gửi đi và nhà phát triển có thể lắng nghe chúng (xem câu trả lời của Raphael bên dưới).
Trong tương lai, chúng tôi sẽ được lưu bởi Entity Manager. Đó là một câu chuyện khác như một khái niệm Magento 2 mới, nhưng nếu bạn muốn để mắt tới, Trình quản lý thực thể đã được triển khai trong Mô hình tài nguyên của trang 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;
}