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

Якщо я додаю ті самі залежності до свого __construct, що і файл, який я з нього поширюю, працює, але, безумовно, це зворотний спосіб робити речі, оскільки точка спадкування класу полягає в тому, що я поглинаю всі методи та властивості батьків?

Я думаю, що мені просто потрібно базове 101 пояснення від когось щодо продовження занять та використання DI з Magento 2. Будь-яка допомога дуже вдячна!


"Безумовно, це зворотний спосіб робити речі" .
Джеймс

Відповіді:


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);
}

Висновок ...
У своїх дочірніх класах потрібно вказати всі параметри батьківського конструктора класів плюс ваші нові параметри. Я не думаю, що порядок важливий, і я не знаю, яка найкраща практика.
Потім в конструкторі ви присвоюєте ваші нові введені об'єкти варам-членам і викликаєте батьківський конструктор з такою ж кількістю параметрів, які йому потрібні.


2
Це має сенс спасибі за вашу відповідь. Я здогадуюсь, я просто сподівався, що це буде більш елегантно, ніж це.
Адам Мосс

Порядок аргументів @Marius має бути таким же, як аргументи батьківського класу __construct методу, ваші власні аргументи потрібно передавати в кінці.
chirag dodia

@chiragdodia Чому? Я не думаю, що так. Все, що я побудував на M2, я створив на основі довільних аргументів, що додаються довільно І це спрацювало. Єдине обмеження полягає в тому, що аргументи зі значенням за замовчуванням мають бути останніми.
Маріус

@Marius так, він працює в деяких випадках, але в моєму випадку, коли у мене є розширення \ Magento \ Каталог \ Блок \ Продукт \ Перегляд його не працює, мені потрібно зробити такий же аргумент, як у батьківському конструкторі, і нарешті додав спеціальні аргументи. Подивіться на мій код тут magento.stackexchange.com/questions/95697/…
chirag dodia

Це не працює для мене, коли я намагався перекрити \ Magento \ Клієнт \ Блок \ Форма \ Реєстрація блоку
DEEP JOSHI
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.