magento2: загрузка пользовательского компонента с помощью Ajax
Я боролся с этим в течение нескольких дней... Для расширения администратора, я пытаюсь загрузить uiComponent с Ajax для отображения на вкладке. Компонент 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();
}
}
Вот простая компоновка контроллера:
<?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>
Примечание. Этот пользовательский компонент uiComponent прекрасно работает при загрузке стандартным (не AJAX) способом.
При отслеживании ответа AJAX я вижу, что загружен правильный HTML-код для uiComponent (включая специальный тег "x-magento-init") для Magento. Затем он обрабатывается обратным вызовом 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 );
})
... для загруженного HTML-кода, который будет вставлен в тег контейнера. Затем в джунглях модулей js обрабатываются куча обратных вызовов и хуков. Событие "contentUpdated" наконец запускается, вызывая:
/**
* Init components inside of dynamically updated elements
*/
$('body').on('contentUpdated', function () {
if (mage) {
mage.apply();
}
});
return $.mage;
}));
Затем mage/apply/main.js и mage/apply/scripts.js правильно вызываются (как отслеживается в консоли браузера), но... ничего не происходит. Мой загружен
<script type="x-magento-init">
исчез, но моя компонентная логика JS вообще не обрабатывается.
Любое просвещение будет высоко ценится.
PS: после более глубокого изучения кажется, что компоненты JS-файлов компонента uiComponent действительно загружаются, но не их шаблоны!
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>