Magento 2の抽象クラスに新しいメソッドを追加する


16

このスレッドが言ったように:Magento 1のMagento 2抽象クラスをオーバーライド

完全に新しいクラスを作成できます。Magento 2では、プラグインを使用する必要がありますが、プラグインでは既存のメソッドを変更することしかできません。新しいメソッドを追加する場合はどうすればよいですか?

例:

このクラスvendor/magento/module-ui/Component/AbstractComponent.phpには、コンポーネントの配列があります:$components、その配列の要素を設定/削除する機能はありません。それでは、どうすればその関数を作成できますか?

回答:


0

クラスを完全にオーバーライドせずにこれを行う方法はわかりません。この例の場合、XMLの「data」引数に「disabled」アイテムを設定することにより、個々のコンポーネントを無効にできます。例えば:

<?xml version="1.0" encoding="UTF-8"?>

<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <fieldset name="general">
        <field name="title">
            <argument name="data" xsi:type="array">
                <item name="disabled" xsi:type="boolean">true</item>
            </argument>
        </field>
    </fieldset>
</form>

これにより、$components配列から「タイトル」が効果的に削除されます。

これはcreateChildComponentMagento\Framework\View\Element\UiComponentFactoryクラスのメソッドによるものです。

 protected function createChildComponent(
        array $bundleComponents,
        ContextInterface $renderContext,
        $identifier
    ) {
        list($className, $arguments) = $this->argumentsResolver($identifier, $bundleComponents);
        if (isset($arguments['data']['disabled']) && (int)$arguments['data']['disabled']) {
            return null;
        }
        $components = [];
        foreach ($bundleComponents['children'] as $childrenIdentifier => $childrenData) {
            $children = $this->createChildComponent(
                $childrenData,
                $renderContext,
                $childrenIdentifier
            );
            $components[$childrenIdentifier] = $children;
        }
        $components = array_filter($components);
        $arguments['components'] = $components;
        if (!isset($arguments['context'])) {
            $arguments['context'] = $renderContext;
        }

        return $this->objectManager->create($className, $arguments);
    }

これは私が探しているものではありません... Abstractクラスに新しいメソッドを追加する方法が必要です...これは単なる例です...たとえば、要素を動的に削除したい場合はどうすればよいですか?あなたのコメントでは、あなたはそれをどのように「完全なオーバーライド」と言っていますか?
マティアス

次に、抽象クラスを拡張するクラスで新しいメソッドを定義し、抽象クラスのサブクラスのクラスを作成して、代わりにクラスを継承してdi.xmlで設定を設定する必要があります。それが、「クラスを完全にオーバーライドする」という意味です。私はそれを避ける方法の例を見せようとしていました。
アーロンアレン

はい、わかりました...しかし、ソリューションはまったくスケーラブルではありません... M2が抽象クラスをオーバーライドする可能性を削除したとは信じられません...削除するのではなく、改善するつもりだったと思います。 。
マティアス


0

コミュニティまたはローカルディレクトリを介してオートローダーでM1のクラスをオーバーロードする(リンクした質問で提案されたような)ことは、非常に良い理由でM1で悪い習慣と見なされました。

ほとんどの場合、元のクラスが場所で変更された場合、Magentoインスタンスをアップグレードする機能を失います。オーバーロードされたクラスでは考慮しませんでした。

実際には、メソッドを抽象クラスに追加する必要があるユースケースは考えられません。独自のロジックを常に独自のクラスに追加して、プラグイン/オブザーバー/ viewModel / xml configに統合できるからです。

最善の方法は、特定のユースケースに合わせて抽象クラスを拡張する新しいクラスを導入し、必要に応じてクラスを使用することです。

Uiコンポーネントから要素を削除する必要がある場合は、レイアウト/レイアウトプロセッサのプラグイン/それを必要とするjsファイルを変更することで、それを実行するより良い方法もあります。

したがって、特定のユースケースを説明する場合、これに対するより良い答えがあるかもしれません。


私はそれを行うのは悪い習慣であることを知っていますが、少なくとも、あなたはそれを行う1つの方法を持っています。たとえば、ロードするモデルごとにキャッシュを追加する場合を考えてください。これは、抽象クラスのloadメソッドを変更することで実行でき、この変更はすべてのクラスに伝播されます。これがない場合は、お持ちの各モデルを変更する必要があり、それはまったくスケーラブルではありません。
マティアス

2番目のユースケースは、チケットで私が言うことをしたい場合、その配列から要素を設定/削除します(例として考えてください)、あなたは他のことを考えることができます...あなたは新しい関数を作成する必要がありますそれ以外の場合、抽象クラスでは、拡張する各クラスで同じ関数を作成する必要がありますが、それはまったくスケーラブルではありません...そして最悪のことには、Magentoコアの変数は保護されるのではなくプライベートであるため、それを行う唯一の方法は、抽象クラスにメソッドを追加することです...
Matias

最初の例は、Aroundプラグインを抽象モデルに追加し、モデルごとのロード結果をキャッシュするだけで、非常に簡単です。これは、抽象モデルが変更される将来のすべての更新を中断する抽象クラスをオーバーロードするよりもはるかに良いでしょう。あなたは基本的にあなたの実際の使用の場合、抽象クラスにメソッドを追加し、代わりに述べるために、正確に頼むので、あなたは、第二の「例」私は、ずっと程度を伝えることはできません
デビッドVerholen

あなたが作曲オートローダを操作することができますので、ところでそれがMagento2ではまだ可能ですが、あなたはアップデートに問題がありますので、非常に落胆magento.stackexchange.com/questions/164455/...を
デビッドVerholen

That'sないオプション
マティアス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.