DIおよびMagento 2でのブロックの拡張


15

\ Magento \ Framework \ View \ Element \ Templateではないブロックを拡張しようとするたびに、Magento 2の依存関係の注入をブロックで把握するのに苦労しているようです。

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に追加した場合、クラス継承のポイントは親のメソッドとプロパティをすべて吸収することなので、確かにそれは逆方向の方法です?

クラスから拡張し、Magento 2でDIを使用する方法について、基本的な101の説明が必要だと思います。


「確かにそれは物事を後進させる方法です」と同意しました。
ジェームズ

回答:


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メソッドの引数と同じである必要があり、カスタム引数は最後に渡す必要があります。
チラグドディア16年

@chiragdodiaなんで?そうは思いません。M2でこれまでに作成したものはすべて、ランダムに追加されたカスタムコンストラクト引数を使用して作成しました。そしてそれは働いた。唯一の制約は、デフォルト値を持つ引数が最後に行くことです。
マリウス

@Mariusはいくつかのケースで動作しますが、私の場合、\ Magento \ Catalog \ Block \ Product \ Viewを拡張すると動作しない場合、親コンストラクタと同じ順序で引数を作成し、最後にカスタム引数を追加する必要があります。ここに私のコードを見てみましょうmagento.stackexchange.com/questions/95697/...
dodiaチラグ

私は\ Magentoの\顧客\ブロック\フォーム\レジスタブロック上書きしようとしたとき、それは私のために働いていない
DEEP女子
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.