DI & ขยายบล็อกบน Magento 2


15

ฉันดูเหมือนจะดิ้นรนที่จะเข้าใจการฉีดขึ้นกับบล็อกของ Magento 2 ทุกครั้งที่ฉันพยายามขยายบล็อกที่ไม่ใช่\ Magento \ Framework \ View \ Element \ Templateฉันท้ายด้วยข้อผิดพลาด

ฉันต้องการสร้างบล็อกที่ขยายคลาสบล็อกพื้นฐานของMagento \ Theme \ Block \ Html \ Header \ Logo - ทุกอย่างทำงานได้ดีจนกระทั่งฉันลองใช้การฉีดพึ่งพาภายในวิธีการสร้าง:

<?php

namespace Creare\Test\Block\Header;

class Logo extends \Magento\Theme\Block\Html\Header\Logo
{

    protected $_creareHelper;

    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        \Creare\Seo\Helper\Data $creareHelper,
        array $data = []
    )
    {
        $this->_creareHelper = $creareHelper;
        parent::__construct($context, $data);
    }
}

ทันทีที่ฉันพยายามฉีดผู้ช่วย (หรืออย่างอื่นสำหรับเรื่องนั้นฉันจะได้รับการติดตามสแต็กเริ่มต้นด้วยข้อผิดพลาดต่อไปนี้:

Recoverable Error: Argument 2 passed to Magento\Theme\Block\Html\Header\Logo::__construct() must be an instance of Magento\MediaStorage\Helper\File\Storage\Database, array given, called in /Users/adammoss/PhpstormProjects/Magento2/app/code/Creare/Test/Block/Header/Logo.php on line 17 and defined in /Users/adammoss/PhpstormProjects/Magento2/app/code/Magento/Theme/Block/Html/Header/Logo.php on line 33

ถ้าฉันเพิ่มการพึ่งพาแบบเดียวกันกับ __ โครงสร้างของฉันเป็นไฟล์ที่ฉันขยายจากมันใช้งานได้ แต่แน่นอนว่ามันเป็นวิธีย้อนหลังในการทำสิ่งต่าง ๆ ที่เป็นจุดสืบทอดของคลาสคือฉันดูดซับวิธีการและคุณสมบัติทั้งหมดของผู้ปกครองหรือไม่

ฉันคิดว่าฉันแค่ต้องการคำอธิบายพื้นฐาน 101 จากใครบางคนเกี่ยวกับการขยายจากชั้นเรียนและใช้ DI กับ Magento 2 ความช่วยเหลือใด ๆ ชื่นชมมาก!


"แน่นอนว่าเป็นวิธีการย้อนกลับของการทำสิ่งต่าง ๆ "ตกลง
James

คำตอบ:


19

คลาสที่คุณพยายามขยายมีตัวสร้างนี้:

public function __construct(
    \Magento\Framework\View\Element\Template\Context $context,
    \Magento\MediaStorage\Helper\File\Storage\Database $fileStorageHelper,
    array $data = []
) {
    $this->_fileStorageHelper = $fileStorageHelper;
    parent::__construct($context, $data);
}

ดังนั้นคุณต้องทำให้คอนสตรัคเตอร์ของคุณเป็นแบบนี้

public function __construct(
    \Magento\Framework\View\Element\Template\Context $context,
    \Magento\MediaStorage\Helper\File\Storage\Database $fileStorageHelper,
    \Creare\Seo\Helper\Data $creareHelper,
    array $data = []
)
{
    $this->_creareHelper = $creareHelper;
    parent::__construct($context, $fileStorageHelper, $data);
}

บทสรุป ...
ในคลาสลูกของคุณคุณต้องระบุพารามิเตอร์คอนสตรัคเตอร์ระดับผู้ปกครองทั้งหมดพร้อมพารามิเตอร์ใหม่ของคุณ ฉันไม่คิดว่าคำสั่งซื้อนั้นสำคัญและฉันไม่รู้ว่าวิธีปฏิบัติที่ดีที่สุดคืออะไร
จากนั้นใน Constructor คุณกำหนดอ๊อบเจ๊กต์ฉีดใหม่ของคุณให้กับสมาชิก vars และเรียกผู้สร้างคอนสตรัคเตอร์ด้วยจำนวนพารามิเตอร์ที่ต้องการ


2
ขอบคุณมากสำหรับคำตอบของคุณ ฉันคิดว่าฉันแค่หวังว่ามันจะสง่างามกว่านั้น
Adam Moss

@Marius ลำดับของอาร์กิวเมนต์ต้องเหมือนกับคลาสพาเรนต์ของเมธอดอาร์กิวเมนต์คลาส __ โครงสร้างอาร์กิวเมนต์ที่กำหนดเองของคุณต้องผ่านในตอนท้าย
chirag dodia

@chiragdodia ทำไม ฉันไม่คิดอย่างนั้น ทุกสิ่งที่ฉันสร้างจนถึง M2 ฉันสร้างโดยใช้อาร์กิวเมนต์การสร้างที่กำหนดเองเพิ่มแบบสุ่ม และมันก็ใช้งานได้ ข้อ จำกัด เพียงอย่างเดียวคือข้อโต้แย้งที่มีค่าเริ่มต้นควรจะผ่านไป
Marius

@Marius ใช่มันทำงานได้ในบางกรณี แต่ในกรณีของฉันเมื่อฉันขยาย \ Magento \ Catalog \ Block \ Product \ ดูมันไม่ทำงานฉันต้องใช้ลำดับของการขัดแย้งเช่นเดียวกับใน constructor หลักและเพิ่มอาร์กิวเมนต์ที่กำหนดเองในที่สุด ลองดูโค้ดของฉันที่นี่magento.stackexchange.com/questions/95697/ …
chirag dodia

มันไม่ทำงานสำหรับฉันเมื่อฉันพยายามแทนที่ \ Magento \ Customer \ Block \ Form \ Register Block
DEEP JOSHI
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.