เพราะมันยากสำหรับฉันที่จะหาวิธีที่ถูกต้องด้านล่างคุณจะได้พบกับแนวปฏิบัติที่ดีที่สุดที่ฉันสร้างขึ้นมา สนุกแก้ไขภาษาอังกฤษของฉันถ้าจำเป็นและบอกฉันฉันผิดถ้าฉันเป็น :)
แก้ไข: ... และฉันพบว่าฉันผิดในบางแง่มุม ดังนั้นฉันจึงอัพเดทโพสต์ต้นฉบับหลังจากคำตอบของราฟาเอลช่วยให้ฉันเข้าใจมากขึ้น ขอบคุณเขา!
แนวคิดที่ใช้ด้านล่าง :
มันจะง่ายขึ้นสำหรับคุณที่จะเข้าใจรหัสและคำอธิบายด้านล่างหากคุณพอใจกับแนวคิดเหล่านี้:
- การฉีดขึ้นอยู่กับ (เป็นทุก ๆ
$this->variableตัวแปรในรหัสจะถูกฉีด) - สัญญาบริการและพื้นที่เก็บข้อมูล
- โรงงาน
บริบท :
เพื่อให้มีบริบทมากขึ้นลองจินตนาการว่าเรามีโมดูลที่สร้างอย่างถูกต้องด้วย:
- คลาสบล็อก CustomBlock ที่มีเมธอด
getCustomModel($id), - เมธอดนี้ส่งคืนออบเจกต์ CustomModel โดยอิงจาก id ที่ส่งเป็น param
- ประเภท CustomModel สอดคล้องกับรูปแบบใน
\Vendor\Module\Model\CustomModel - โมเดลนี้มาพร้อมกับโมเดลทรัพยากร (ใน
\Vendor\Module\Model\ResourceModel\CustomModel) - และด้วยที่เก็บ (ใน
\Vendor\Module\Model\CustomModelRepository)
คำถาม :
- แนวปฏิบัติที่ดีที่สุดในการปล่อยให้ทุกสิ่งโหลดวัตถุ CustomModel คืออะไร
คุณไม่สามารถใช้load()จากวัตถุ CustomModel เนื่องจากวิธีนี้เลิกใช้แล้ว
แนวปฏิบัติที่ดีบอกว่าคุณต้องใช้ CustomModel Service Contract สัญญาบริการคือส่วนต่อข้อมูล (เช่น CustomModelInterface) และส่วนต่อประสานบริการ (เช่น CustomModelRepositoryInterface) ดังนั้นบล็อกของฉันมีลักษณะดังนี้:
/ ** @var SlideRepositoryInterface * /
ป้องกัน $ slideRepository;
/ **
* ตัวสร้าง CustomBlock
* ...
* @param CustomModelRepositoryInterface $ customModelRepository
* ...
* /
ฟังก์ชั่นสาธารณะ __ โครงสร้าง (
...
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 Interface ของฉันถูกเรียกโดยการฉีดพึ่งพาในตัวสร้างบล็อกของฉันรหัสอยู่ที่ไหน สำหรับคำตอบของคำถามนี้คุณต้องอธิบายให้ Magento ทราบว่าชั้นเรียนใดที่ใช้อินเทอร์เฟซนี้ ในไฟล์ etc / di.xml ของโมดูลคุณต้องเพิ่ม:
<preference for="Vendor\Module\Api\CustomModelRepositoryInterface" type="Vendor\Module\Model\CustomModelRepository" />
ดังนั้นCustomModelRepositoryInterfaceระดับเป็นอินเตอร์เฟซให้บริการ ในการดำเนินการนั้นคุณจะต้องนำไปใช้กับ data interface (อย่างน้อย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 ที่มี id "% 1" ไม่มีอยู่', $ id));
}
ส่งกลับ $ customModel;
}
เรากำลังทำอะไร เราสร้างCustomModelวัตถุเปล่าด้วยโรงงาน ต่อไปเราจะโหลดข้อมูลCustomModelโดยใช้วิธีการโหลดโมเดล ต่อไปเราจะคืนค่า a NoSuchEntityExceptionหากเราไม่สามารถโหลดCustomModelด้วย id ใน params แต่ถ้าทุกอย่างโอเคเราคืนวัตถุต้นแบบและชีวิตดำเนินต่อไป
แต่ว้าว ... ! ในตัวอย่างนี้คืออะไร
$customModel->load($id);
ไม่ใช่loadวิธีการที่เลิกใช้แล้วมากกว่าตอนต้นใช่ไหม? ใช่แล้ว. ฉันคิดว่ามันน่าละอาย แต่คุณต้องใช้มันตั้งแต่วิธีการโหลด () นี้มีกิจกรรมบางอย่างที่จัดส่งและนักพัฒนาสามารถฟังพวกเขา (ดูคำตอบของราฟาเอลด้านล่าง)
ในอนาคตเราจะได้รับการช่วยเหลือจาก Entity Manager นี่เป็นอีกเรื่องหนึ่งที่เป็นแนวคิดใหม่ของ Magento 2 แต่หากคุณต้องการจับตาดู Entity Manager จะถูกนำไปใช้ใน Resource Model ของ 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;
}