Magento 2:如何在UiComponent中添加动态URL以进行Ajax调用?

4
我是使用UiComponent来创建一个表单。在options.js中,我想要进行ajax调用,但是出现了404未找到错误。我想知道如何获取正确的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调用。

2个回答

3

我尝试了各种方法将一个url动态地引入到UI组件中,但我认为标准且安全的方式是通过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();
        },
    });
});

编辑:我已经更新了以下的答案。


2
<最初的回答>:此外,还可以通过url XML数据类型添加(仅限静态URL)。在这种情况下,无需修改元数据。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();
        },
    });
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接