Aggiunta di un nuovo metodo a una classe astratta in Magento 2


16

Come ha detto questo thread: Sostituisci classe astratta in Magento 2 in Magento 1 ,

Posso solo creare una classe completamente nuova. In Magento 2, abbiamo bisogno di usare plugin, ma i plugin mi permettono solo di modificare metodi esistenti. Cosa devo fare se voglio aggiungere un nuovo metodo?

Esempio:

Questa classe vendor/magento/module-ui/Component/AbstractComponent.phpha una matrice di componenti: $componentsnon esiste alcuna funzione per annullare / cancellare gli elementi per quella matrice. Quindi, come posso creare quella funzione?

Risposte:


0

Non vedo come puoi farlo senza scavalcare completamente la classe. Nel caso del tuo esempio, puoi disabilitare singoli componenti impostando la voce "disabilitato" sull'argomento "dati" nell'XML. Per esempio:

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

Questo rimuove efficacemente "titolo" $componentsdall'array.

Ciò è dovuto al createChildComponentmetodo nella Magento\Framework\View\Element\UiComponentFactoryclasse:

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

Questo non è quello che sto cercando ... Voglio un modo per aggiungere nuovi metodi a una classe Abstract ... questo è solo un esempio ... per esempio, e se volessi rimuovere gli elementi in modo dinamico? Nel tuo commento menzioni "completa sostituzione" come lo fai ??
Matias,

Quindi dovrai definire i tuoi nuovi metodi in una classe che estende la classe astratta e quindi creare classi per le sottoclassi della classe astratta che invece ereditano dalla tua classe e impostano le preferenze in di.xml. Questo è ciò che intendo per "scavalcare completamente la classe". Stavo cercando di mostrare un esempio di come evitare di farlo.
Aaron Allen,

Sì, ti capisco ... ma la soluzione non è affatto scalabile ... Non riesco a credere che M2 abbia rimosso la possibilità di scavalcare le classi astratte ... Pensavo che l'avrebbero migliorata, invece di rimuoverla .. .
Matias


0

sovraccaricare una classe in M1 nel caricatore automatico tramite la community o la directory locale (come suggerito nella domanda che hai collegato) è stata considerata una cattiva pratica in M1 per ottime ragioni.

Principalmente perdi la possibilità di aggiornare l'istanza di Magento se la classe originale viene modificata in alcuni punti, non considerata nella classe sovraccarica.

In realtà, non riesco a pensare a nessun caso d'uso, in cui è davvero necessario aggiungere metodi a una classe astratta, poiché è sempre possibile aggiungere la propria logica a una propria classe e integrarla in una configurazione plugin / observer / viewModel / xml

Il modo migliore sarebbe quello di introdurre una nuova classe che estende la classe astratta per il tuo caso d'uso specifico e quindi usa la classe dove necessario.

Se è necessario rimuovere elementi da un componente Ui, esiste probabilmente anche un modo migliore per farlo tramite layout / plug-in sul processore di layout / modificare il file js che lo richiede.

Quindi, se descrivi il tuo caso specifico, potrebbe esserci una risposta migliore a questo.


So che farlo è una cattiva pratica, ma almeno hai un modo per farlo. Ad esempio, considera il caso in cui desideri aggiungere una cache per ogni singolo modello che carichi. Questo potrebbe essere fatto modificando il metodo di caricamento nella classe astratta e quindi questa modifica verrà propagata a tutte le classi. Se non lo hai, devi modificare ogni modello che hai, e questo non è assolutamente scalabile.
Matias,

Un secondo caso d'uso, potrebbe essere se vuoi fare quello che dico nel ticket, disinserire / eliminare elementi da quell'array (considera un esempio), puoi pensare a qualsiasi altra cosa ... devi creare una nuova funzione nella classe astratta, altrimenti, sarai costretto a creare la stessa funzione in ogni classe che si estende e che di nuovo non è affatto scalabile ... E peggio, perché le variabili nel core di Magento sono private invece di essere protette, quindi il l'unico modo per farlo è aggiungere un metodo nella classe astratta ...
Matias,

il primo esempio è assolutamente semplice semplicemente aggiungendo un plugin around al modello astratto e memorizzando nella cache il risultato del caricamento per modello. Il che sarebbe molto meglio che sovraccaricare la classe astratta che interromperebbe ogni aggiornamento futuro in cui il modello astratto viene cambiato. Secondo secondo "esempio" di cui non posso parlarti molto, perché sostanzialmente stai chiedendo esattamente di aggiungere un metodo alla classe astratta, invece di
indicare il

btw è ancora possibile in Magento2 perché puoi manipolare il caricatore automatico del compositore, ma altamente scoraggiato perché avrai problemi con gli aggiornamenti magento.stackexchange.com/questions/164455/…
David Verholen,

Questa non è un'opzione
Matias il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.