Menambahkan metode baru ke Kelas Abstrak di Magento 2


16

Seperti utas ini: Timpa kelas abstrak di Magento 2 di Magento 1 ,

Saya hanya bisa membuat kelas baru sepenuhnya. Di Magento 2, kita perlu menggunakan plugin, tetapi plugin hanya memungkinkan saya untuk memodifikasi metode yang ada. Apa yang harus saya lakukan jika saya ingin menambahkan metode baru?

Contoh:

Kelas ini vendor/magento/module-ui/Component/AbstractComponent.php, memiliki array komponen $components:, tidak ada fungsi untuk membatalkan / menghapus elemen untuk array itu. Jadi bagaimana saya bisa membuat fungsi itu?

Jawaban:


0

Saya tidak melihat bagaimana Anda bisa melakukan itu tanpa sepenuhnya mengesampingkan kelas. Dalam hal contoh Anda, Anda dapat menonaktifkan komponen individu dengan mengatur item "dinonaktifkan" ke argumen "data" dalam XML. Contohnya:

<?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>

Ini secara efektif menghapus 'judul' dari $componentsarray.

Ini disebabkan oleh createChildComponentmetode di Magento\Framework\View\Element\UiComponentFactorykelas:

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

Ini bukan yang saya cari ... Saya ingin cara untuk menambahkan metode baru ke kelas Abstrak ... ini hanya sebuah contoh ... misalnya, bagaimana jika saya ingin menghapus elemen secara dinamis? Dalam komentar Anda, Anda menyebutkan "sepenuhnya menimpa" bagaimana Anda melakukannya ??
Matias

Maka Anda perlu mendefinisikan metode baru Anda di kelas yang memperluas kelas abstrak dan kemudian membuat kelas untuk subkelas kelas abstrak yang sebaliknya mewarisi dari kelas Anda dan mengatur preferensi di di.xml. Itulah yang saya maksud dengan 'sepenuhnya mengesampingkan kelas.' Saya mencoba menunjukkan contoh bagaimana menghindari melakukan itu.
Aaron Allen

Ya, saya mengerti Anda ... tetapi solusinya tidak scalable sama sekali ... Saya tidak percaya bahwa M2 menghapus kemungkinan meng-override kelas abstrak ... Saya pikir mereka akan memperbaikinya, daripada menghapusnya .. .
Matias


0

kelebihan kelas di M1 di autoloader melalui komunitas atau direktori lokal (seperti yang disarankan dalam pertanyaan yang Anda tautkan) dianggap praktik buruk di M1 karena alasan yang sangat bagus.

Sebagian besar Anda kehilangan kemampuan untuk memutakhirkan instance Magento Anda jika kelas asli diubah di beberapa tempat, Anda tidak mempertimbangkan di kelas kelebihan beban Anda.

Sebenarnya, saya tidak dapat memikirkan usecase apa pun, di mana Anda benar-benar perlu menambahkan metode ke kelas abstrak, karena Anda selalu dapat menambahkan logika Anda sendiri ke kelas sendiri dan mengintegrasikannya dalam plugin / observer / viewModel / xml config

Cara terbaik adalah memperkenalkan kelas baru yang memperluas kelas abstrak untuk kasus penggunaan spesifik Anda dan kemudian menggunakan kelas Anda di mana diperlukan.

Jika Anda perlu menghapus elemen dari Komponen Ui, ada kemungkinan juga cara yang lebih baik untuk melakukannya melalui tata letak / plugin pada prosesor tata letak / mengubah file js yang membutuhkannya.

Jadi, jika Anda menggambarkan penggunaan spesifik Anda, mungkin ada jawaban yang lebih baik untuk ini.


Saya tahu, melakukan itu adalah praktik yang buruk, tetapi setidaknya, Anda punya satu cara untuk melakukannya. Misalnya, pertimbangkan case yang ingin Anda tambahkan cache untuk setiap model tunggal yang Anda muat. Ini bisa dilakukan dengan memodifikasi metode beban di kelas abstrak dan kemudian perubahan ini akan disebarkan ke semua kelas. Jika Anda tidak memiliki ini, Anda harus memodifikasi setiap model yang Anda miliki, dan itu sama sekali tidak dapat diskalakan sama sekali.
Matias

Kasus penggunaan kedua, bisa jadi jika Anda ingin melakukan apa yang saya katakan di tiket, membatalkan / menghapus elemen dari array itu (pertimbangkan sebagai contoh), Anda dapat memikirkan hal lain apa pun ... Anda perlu membuat fungsi baru di kelas abstrak, jika tidak, Anda akan dipaksa untuk membuat fungsi yang sama di setiap kelas yang meluas, dan itu lagi tidak dapat diskalakan sama sekali ... Dan yang terburuk, karena variabel dalam inti Magento bersifat pribadi alih-alih dilindungi, sehingga satu-satunya cara untuk melakukannya adalah dengan menambahkan metode dalam kelas abstrak ...
Matias

contoh pertama sangat mudah hanya dengan menambahkan plugin sekitar ke model abstrak dan cache hasil dari load per model. Yang akan jauh lebih baik daripada membebani kelas abstrak yang akan memecah setiap pembaruan di masa depan di mana model abstrak diubah. Anda "contoh" kedua, saya tidak bisa memberi tahu Anda banyak tentang, karena pada dasarnya Anda meminta tepat untuk menambahkan metode ke kelas abstrak, alih-alih menyatakan kasus penggunaan yang sebenarnya
David Verholen

btw itu masih mungkin di Magento2 karena Anda dapat memanipulasi komposer autoloader, tetapi sangat berkecil hati karena Anda akan memiliki masalah dengan pembaruan magento.stackexchange.com/questions/164455/…
David Verholen

Itu bukan pilihan
Matias
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.