เพราะมันยากสำหรับฉันที่จะหาวิธีที่ถูกต้องด้านล่างคุณจะได้พบกับแนวปฏิบัติที่ดีที่สุดที่ฉันสร้างขึ้นมา สนุกแก้ไขภาษาอังกฤษของฉันถ้าจำเป็นและบอกฉันฉันผิดถ้าฉันเป็น :)
แก้ไข: ... และฉันพบว่าฉันผิดในบางแง่มุม ดังนั้นฉันจึงอัพเดทโพสต์ต้นฉบับหลังจากคำตอบของราฟาเอลช่วยให้ฉันเข้าใจมากขึ้น ขอบคุณเขา!
แนวคิดที่ใช้ด้านล่าง :
มันจะง่ายขึ้นสำหรับคุณที่จะเข้าใจรหัสและคำอธิบายด้านล่างหากคุณพอใจกับแนวคิดเหล่านี้:
- การฉีดขึ้นอยู่กับ (เป็นทุก ๆ
$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;
}