在Magento 2中为Abstract类添加新方法


16

就像这个线程所说的那样:在Magento 1中覆盖Magento 2中的抽象类

我可以创建一个全新的类。在Magento 2中,我们需要使用插件,但是插件仅允许我修改现有方法。如果我想添加新方法该怎么办?

例:

此类vendor/magento/module-ui/Component/AbstractComponent.php具有一个数组数组:$components,没有用于取消/删除该数组元素的函数。那么如何创建该功能呢?

Answers:


0

我看不到如何在不完全重写课程的情况下做到这一点。在您的示例中,可以通过将XML中的“ disabled”项设置为“ data”参数来禁用单个组件。例如:

<?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数组中删除了“标题” 。

这是由于该类中的createChildComponent方法Magento\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类添加新方法的方法...这只是一个示例...例如,如果我想动态删除元素怎么办?在您的评论中,您提到“完全覆盖”您是如何做到的?
Matias'8

然后,您需要在扩展抽象类的类中定义新方法,然后为抽象类的子类创建类,这些子类继承自您的类并在di.xml中设置首选项。我的意思是“完全超越班级”。我试图显示一个避免这样做的例子。
亚伦·艾伦

是的,我理解您...但是该解决方案根本无法扩展...我不敢相信M2消除了覆盖抽象类的可能性...我认为他们将改进而不是删除它。 。
马蒂亚斯


0

在M1中通过社区或本地目录重载自动加载器中M1中的类(如您所链接的问题中所建议的),由于非常好的原因,在M1中被认为是不好的做法。

通常,如果原始类在某些地方发生了更改,则您将失去升级Magento实例的能力,而您未在重载的类中考虑。

实际上,我想不出任何用例,您确实需要在抽象类中添加方法,因为您总是可以将自己的逻辑添加到自己的类中并将其集成到插件/观察者/ viewModel / xml配置中

最好的方法是,引入一个新类,为您的特定用例扩展抽象类,然后在需要时使用您的类。

如果您需要从Ui组件中删除元素,则还有一种更好的方法可以通过layout /布局处理器上的插件/更改需要它的js文件来实现。

因此,如果您描述您的特定用例,则可能会有更好的答案。


我知道,这样做是不好的做法,但是至少,您有一种方法可以做到这一点。例如,考虑要为加载的每个模型添加缓存的情况。这可以通过修改抽象类中的load方法来完成,然后将此更改传播到所有类。如果您没有此功能,则必须修改您拥有的每个模型,这绝对是不可扩展的。
Matias

第二个用例可能是,如果您想执行我在票证中所说的,从该数组中取消设置/删除元素(以示例为例),您可以考虑其他事情...您需要创建一个新函数在抽象类中,否则,您将被迫在每个扩展的类中创建相同的函数,而该类又根本无法扩展...而且最糟糕的是,由于Magento核心中的变量是私有的而不是受保护的,因此唯一的方法是在抽象类中添加一个方法...
Matias 19'Jan

第一个示例非常简单,只需在抽象模型中添加一个around插件并缓存每个模型的加载结果即可。这将比重载抽象类好得多,这将使将来更改抽象模型的每次更新都中断。第二个“示例”我不能告诉您太多,因为您基本上是在要求向抽象类添加方法,而不是说明您的实际用例
David Verholen

顺便说一句,它仍然有可能在Magento2,因为你可以操纵作曲家自动加载,但非常沮丧,因为你将有更新的问题magento.stackexchange.com/questions/164455/...
大卫Verholen

那不是一个选择
Matias
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.