magento2:使用Ajax加载uicomponent

Man*_*n4x 5 ajax uicomponents magento2

几天来,我一直在为此苦苦挣扎...对于管理员扩展,我正尝试使用Ajax加载uiComponent以便在选项卡中显示。uiComponent已正确加载,但似乎未由客户端敲除逻辑完全处理。

namespace Man4x\MondialRelay2\Block\Adminhtml\Shipping;

class Tabs
extends \Magento\Backend\Block\Widget\Tabs {
protected function _construct()
{
    parent::_construct();
    $this->setId('mondialrelay2_shipping_tabs');
    $this->setDestElementId('container');
    $this->setTitle(__('MondialRelay'));
} 

protected function _beforeToHtml()
{
    $this->addTab(
        'mass_shipping',
        [
            'label' => __('Mass Shipping'),
            'title' => __('Mass Shipping'),
            'url'   => $this->getUrl('*/*/massshipping', ['_current' => true]),
            'class'  => 'ajax'
        ]
    );

    return parent::_beforeToHtml();
}
}
Run Code Online (Sandbox Code Playgroud)

这是简单的控制器布局:

<?xml version="1.0"?>

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<container name="root" label="Root">
    <uiComponent name="mondialrelay2_massshipping_grid"/>
</container>
Run Code Online (Sandbox Code Playgroud)

注意:以标准方式(即非AJAX)加载时,此自定义uiComponent可以完美地发挥功能

跟踪AJAX响应时,我可以看到已为uiComponent加载了正确的HTML代码(包括Magento特定的“ x-magento-init”标签)。然后由jquery-ui回调处理:

    this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );

    // support: jQuery <1.8
    // jQuery <1.8 returns false if the request is canceled in beforeSend,
    // but as of 1.8, $.ajax() always returns a jqXHR object.
    if ( this.xhr && this.xhr.statusText !== "canceled" ) {
        tab.addClass( "ui-tabs-loading" );
        panel.attr( "aria-busy", "true" );

        this.xhr
            .success(function( response ) {
                // support: jQuery <1.8
                // http://bugs.jquery.com/ticket/11778
                setTimeout(function() {
                    panel.html( response );
                    that._trigger( "load", event, eventData );
                }, 1 );
            })
Run Code Online (Sandbox Code Playgroud)

...用于将要插入的HTML代码插入容器标签中。然后,在js模块丛林中处理一堆回调和挂钩。最终触发“ contentUpdated”事件,导致:

/**
 * Init components inside of dynamically updated elements
 */
$('body').on('contentUpdated', function () {
    if (mage) {
        mage.apply();
    }
});

return $.mage;
}));
Run Code Online (Sandbox Code Playgroud)

然后正确调用了mage / apply / main.js和mage / apply / scripts.js(在浏览器控制台中进行了跟踪),但是...没有任何反应。我装好了

<script type="x-magento-init">
Run Code Online (Sandbox Code Playgroud)

消失了,但是我的组件JS逻辑根本不处理。

任何启发将不胜感激。

PS:经过更深入的调查,似乎实际上已加载uiComponent的组件JS文件,但未加载其模板!

小智 1

我在类似的场景中遇到了与您相同的问题。在这种情况下,绑定似乎没有按应有的方式应用,或者至少没有在应有的时候应用。为了在不改变模板的情况下修复它,我求助于一些额外的 xml,在您的情况下,这可能是:

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<container name="root" label="Root" htmlTag="div" htmlId="mondialrelay2">
    <uiComponent name="mondialrelay2_massshipping_grid"/>
    <block class="Magento\Framework\View\Element\Text" name="ajax_ui_component_fix">
        <action method="setText">
            <argument name="text" xsi:type="string"><![CDATA[<script>
                require(['jquery'], function ($) {
                    $('#mondialrelay2').applyBindings();
                });
            </script>]]></argument>
        </action>
    </block>
</container>
Run Code Online (Sandbox Code Playgroud)