<fieldset name="product-details">
    <field name="sku">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="notice" xsi:type="string" translate="true" after="product-details.sku">Some note here</item>
            </item>
        </argument>
    </field>
</fieldset>

I have tried this, which should just add notice below existing input, but it is adding new (duplicated) SKU field and displaying notice with that. So how can I override existing field/attribute?

有帮助吗?

解决方案

The correct way to update the product form in your module (using xml):

app/code/Vendor/Module/view/adminhtml/ui_component/category_form.xml

<?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="product-details">
        <container name="container_sku">
            <field name="sku" formElement="input">
                <settings>
                    <notice translate="true">Some note here</notice>
                    <label translate="true">SKU-SKU-SKU</label>
                </settings>
            </field>
        </container>
    </fieldset>
</form>

but it will no work, because the Magento use own modifiers to declare product form fields:

vendor/magento/module-catalog/Ui/DataProvider/Product/Form/ProductDataProvider.php

/**
 * {@inheritdoc}
 * @since 101.0.0
 */
public function getMeta()
{
    $meta = parent::getMeta();

    /** @var ModifierInterface $modifier */
    foreach ($this->pool->getModifiersInstances() as $modifier) {
        $meta = $modifier->modifyMeta($meta);
    }

    return $meta;
}

and meta-data returned by this method merged with .xml declaration with highest priority. It's mean that your data from xml will be overwriten by data with same keys from data provider in this method:

vendor/magento/framework/View/Element/UiComponentFactory.php

/**
 * Merge data provider's metadata to components
 *
 * @param string $identifier
 * @param array $bundleComponents
 * @param bool $reverseMerge
 * @return array
 * @since 100.1.0
 */
protected function mergeMetadata($identifier, array $bundleComponents, $reverseMerge = false)
{
    $dataProvider = $this->getDataProvider($identifier, $bundleComponents);
    if ($dataProvider instanceof DataProviderInterface) {
        $metadata = [
            $identifier => [
                'children' => $dataProvider->getMeta(),
            ],
        ];
        $bundleComponents = $this->mergeMetadataItem($bundleComponents, $metadata, $reverseMerge);
    }

    return $bundleComponents;
}

as a result your component settings declared by same path in xml will be overwritten by empty\null\default values in case it exists in the base Magento declaration.

To get around that problem we need to add own modifier to the product form modifiers pool and update base declaration inside:

Add module sequence:

app/code/Vendor/Module/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Vendor_Module" setup_version="0.0.1">
        <sequence>
            <module name="Magento_Catalog"/>
            <module name="Magento_Ui"/>
        </sequence>
    </module>
</config>

Add own modifier to pool:

app/code/Vendor/Module/etc/adminhtml/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <virtualType name="Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Pool">
        <arguments>
            <argument name="modifiers" xsi:type="array">
                <item name="custom_sku_modifier" xsi:type="array">
                    <item name="class" xsi:type="string">Vendor\Module\Ui\DataProvider\Product\Form\Modifier\Sku</item>
                    <item name="sortOrder" xsi:type="number">200</item>
                </item>
            </argument>
        </arguments>
    </virtualType>
</config>

Add modifier class:

app/code/Vendor/Module/Ui/DataProvider/Product/Form/Modifier/Sku.php

<?php
namespace Vendor\Module\Ui\DataProvider\Product\Form\Modifier;

/**
 * Class Sku
 */
class Sku extends \Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier
{

    /**
     * @param array $data
     * @return array
     * @since 100.1.0
     */
    public function modifyData(array $data)
    {
        return $data;
    }

    /**
     * @param array $meta
     * @return array
     * @since 100.1.0
     */
    public function modifyMeta(array $meta)
    {
        if (isset($meta['product-details']['children']['container_sku']['children']['sku']
            ['arguments']['data']['config'])
        ) {
            $skuConfig = &$meta['product-details']['children']['container_sku']['children']
            ['sku']['arguments']['data']['config'];
            $skuConfig['notice'] = __('Some note here');
        }

        return $meta;
    }
}

Here is result in admin form:

result example

许可以下: CC-BY-SA归因
scroll top