Magento 2:如何为来自 UiComponent 的 Ajax 调用添加动态 url?

Magento 2 : How to add dynamic url for Ajax call from UiComponent?

我正在使用 UiComponent 制作表单。在 options.js,我想打一个 ajax 电话。但是它出现 404 not found 错误。我想知道我们如何才能得到正确的 url.

形式为:

<field name="attribute_id">
    <argument name="data" xsi:type="array">
        <item name="options" xsi:type="object">Vendor\Module\Model\Source\Myvalues</item>
        <item name="config" xsi:type="array">
            <item name="dataType" xsi:type="string">text</item>
            <item name="label" translate="true" xsi:type="string">Attribute</item>
            <item name="component" xsi:type="string">Vendor_Module/js/form/element/options</item>
            <item name="formElement" xsi:type="string">select</item>
            <item name="sortOrder" xsi:type="number">210</item>
        </item>
    </argument>
</field>

在options.js

define([
    'jquery',
    'underscore',
    'uiRegistry',
    'Magento_Ui/js/form/element/select',
    'Magento_Ui/js/modal/modal',
    'mage/url'
], function ($, _, uiRegistry, select, modal, url) {
    'use strict';

    return select.extend({

        /**
         * On value change handler.
         *
         * @param {String} value
         */
        onUpdate: function (value) {
            console.log('Selected Value: ' + value);

            var field1 = uiRegistry.get('index = field1');

  var field2 = uiRegistry.get('index = field2');
  field2.hide();
  var field3Depend1 = uiRegistry.get('index = field3Depend1');


console.log(field2.visibleValue);
 var linkUrl = url.build('customajax');
  console.log('linkurl='+linkUrl);

 //var name = document.getElementsByName("product[name]")[0].value;
   // var type = document.getElementsByName("product[product_category_type]")[0].value;

    $.ajax({
        url: 'BASEURL????'+linkUrl,
        showLoader: true,
        data: {form_key: window.FORM_KEY, 'value':value},
        type: "POST",
          dataType : 'json',
        success: function(result){

            alert(result);
        }
    });


         return this._super();
        },
    });
});

它给出了 404 未找到错误。我想拨打 ajax 电话。

我尝试了各种方法将 url 动态引入 UI 组件,但我认为标准且安全的方法是通过 meta 添加 UI xml 组件本身。

要在组件中注入动态数据(如果您只想添加静态 URL,则不需要)使用以下代码:

表格DataProvider.php:

<?php

namespace Vendor\Module\Ui\DataProvider\Profile;

use Magento\Framework\UrlInterface;

class DataProvider extends \Magento\Ui\DataProvider\AbstractDataProvider
{
    public $collection;

    /**
     * @var $addFieldStrategies
     */
    public $addFieldStrategies;

    /**
     * @var $addFilterStrategies
     */
    public $addFilterStrategies;

    /** @var UrlInterface  */
    public $url;

    public function __construct(
        $name,
        $primaryFieldName,
        $requestFieldName,
        UrlInterface $url,
        \Vendor\Module\Model\ResourceModel\MyModel\CollectionFactory $collectionFactory,
        $addFieldStrategies = [],
        $addFilterStrategies = [],
        $meta = [],
        $data = []
    ) {
        parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data);
        $this->url = $url;
        $this->collection = $collectionFactory->create();
        $this->addFieldStrategies = $addFieldStrategies;
        $this->addFilterStrategies = $addFilterStrategies;
    }

    /**
     * @return array
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function getMeta()
    {
        $meta = parent::getMeta();
        // general -> fieldset name
        // attribute_id -> field name
        $meta["general"]['children']["attribute_id"]['arguments']['data']['config']['url'] =
            $this->url->getUrl('myfrontname/mycontroller/myaction', ['_nosid' => true]);

        return $meta;
    }

    /**
     *
     * @return array
     */
    public function getData()
    {
        if (!$this->getCollection()->isLoaded()) {
            $this->getCollection()->load();
        }

        /** @var array $items */
        $items = $this->getCollection();
        $data = [];

        foreach ($items as &$item) {
            $item->setData("id_field_name", 'id');
            $data[$item->getId()] = $item->getData();
        }
        return $data;
    }
}

这里,函数 getMeta() 正在注入 URL 值。

UI 组件 xml 字段:

<field name="attribute_id">
    <argument name="data" xsi:type="array">
        <item name="options" xsi:type="object">Vendor\Module\Model\Source\Myvalues</item>
        <item name="config" xsi:type="array">
            <item name="url" xsi:type="string" />
            <item name="url" xsi:type="url" path="mymodule/mycontroller/myaction">
                        <param name="_nosid">1</param>
                    </item>
            <item name="dataType" xsi:type="string">text</item>
            <item name="label" translate="true" xsi:type="string">Attribute</item>
            <item name="component" xsi:type="string">Vendor_Module/js/form/element/options</item>
            <item name="formElement" xsi:type="string">select</item>
            <item name="sortOrder" xsi:type="number">210</item>
        </item>
    </argument>
</field>

在这里,我添加了 <item name="url" xsi:type="url" path="mymodule/mycontroller/myaction"> <param name="_nosid">1</param> </item> url 键将具有动态 URL 并将在 JS UI 组件上可用。

现在 options.js,使用 url 字段如下:

define([
    'jquery',
    'underscore',
    'uiRegistry',
    'Magento_Ui/js/form/element/select',
    'Magento_Ui/js/modal/modal',
    'mage/url'
], function ($, _, uiRegistry, select, modal, url) {
    'use strict';

    return select.extend({

        /**
         * On value change handler.
         *
         * @param {String} value
         */
        onUpdate: function (value) {
            // As `this` context will not be available inside ajax,
            // so either use local variable `self` or prepare the URL outside the `$.ajax`  
            var self = this;

            console.log('Selected Value: ' + value);

            var field1 = uiRegistry.get('index = field1');

            var field2 = uiRegistry.get('index = field2');
            field2.hide();
            var field3Depend1 = uiRegistry.get('index = field3Depend1');
            var linkUrl = url.build('customajax');

            $.ajax({
                url: self.url + linkUrl,
                showLoader: true,
                data: {form_key: window.FORM_KEY, 'value':value},
                type: "POST",
                dataType : 'json',
                success: function(result) {
                    alert(result);
            }
         });


         return this._super();
        },
    });
});

编辑:我已将答案更新为以下答案。

也可以通过url xml数据类型添加(只能添加静态url,此时无需修改meta。)

UI 组件 xml 字段:

<dataSource name="your_module_data_source">
        <argument name="dataProvider" xsi:type="configurableObject">
            <argument name="class" xsi:type="string">Your\Module\Data\Provider</argument>
            <argument name="name" xsi:type="string">your_module_data_source</argument>
            <argument name="primaryFieldName" xsi:type="string">id</argument>
            <argument name="requestFieldName" xsi:type="string">id</argument>
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="submit_url" xsi:type="url" path="*/*/save"/>
                    <item name="validate_url" xsi:type="url" path="*/*/validate"/>
                    <item name="get_custom_url" xsi:type="url" path="your/custom/url"/>
                </item>
            </argument>
        </argument>
        <argument name="data" xsi:type="array">
            <item name="js_config" xsi:type="array">
                <item name="component" xsi:type="string">Magento_Ui/js/form/provider</item>
            </item>
        </argument>
    </dataSource>

在这里,我添加了类型为 urlget_custom_url,它将具有 URL 并将在 JS 上可用。

现在 options.js,使用 url 字段如下:

define([
    'jquery',
    'underscore',
    'uiRegistry',
    'Magento_Ui/js/form/element/select',
    'Magento_Ui/js/modal/modal',
    'mage/url'
], function ($, _, uiRegistry, select, modal, url) {
    'use strict';

    return select.extend({

        /**
         * On value change handler.
         *
         * @param {String} value
         */
        onUpdate: function (value) {
            console.log('Selected Value: ' + value);

            var field1 = uiRegistry.get('index = field1');

            var field2 = uiRegistry.get('index = field2');
            field2.hide();
            var field3Depend1 = uiRegistry.get('index = field3Depend1');
            var linkUrl = url.build('customajax');

            var source = uiRegistry.get(this.provider);
            var ajaxUrl = source.get_custom_url;
            $.ajax({
                url: ajaxUrl + linkUrl,
                showLoader: true,
                data: {form_key: window.FORM_KEY, 'value':value},
                type: "POST",
                dataType : 'json',
                success: function(result) {
                    alert(result);
            }
         });


         return this._super();
        },
    });
});