Ajax 通话期间 TYPO3 Flexform 设置不可用

TYPO3 Flexform Settings not available during Ajax call

对于我的 TYPO3 Extbase 扩展,我想做一些分页。 ajax 电话和其他一切到目前为止都很好。但是,当我在 ajax 调用期间尝试访问 $this->settings 数组时,我总是得到 null,其中存储了 flexform 前端插件值。该部分如下所示:

$limit = $this->settings['result']['amount'];
$orderType = $this->settings['order']['type'];
$orderFields = $this->settings['additionorder']['fields'];

$formArr = array();
$this->request->hasArgument('offset') ? $offset = $this->request->getArgument('offset') : null;
$forms = $this->formRepository->findFormsChunked(
$orderFields, $orderType, $limit, $offset
);

foreach ($forms as $key => $form) {
         $formArr[] = array(
                    'formUid' => $form->getUid(),
                    'formName' => $form->getName(),
                    'formFile' => $form->getFile()->getOriginalResource()->getPublicUrl(),
                    'formType' => $form->getFormtype()->getUid()
                );
            }
 return json_encode($formArr);

并且 $this->settings 在我的 ajax 调用期间为空,但我无法想象为什么。这些值是否仅在渲染过程中可用,而在 ajax 调用期间不会发生?

感谢您的帮助。

更新

据我所知,flexform 值仅传递给 selected 控制器操作(即 displaycond),如下所示:

 <displayCond>FIELD:switchableControllerActions:=:Controller->ajax:AND:FIELD:switchableControllerActions:=:Controller->normal</displayCond>

并在 select 菜单中:

                               <numIndex index="1">
                                    <numIndex index="0">LLL:EXT:ext_formpool/Resources/Private/Language/locallang.xlf:name</numIndex>
                                    <numIndex index="1">Controller->normal;Controller->ajax</numIndex>
                                </numIndex>

所以值也应该传递给 ajaxAction?目前他们不可用...

解决方案

不幸的是,如果您使用单独的页面类型进行 ajax 调用,它根本不起作用。 flexform 存储在数据库中,仅在框架加载过程中被解析。您可以通过包含配置管理器来检查这一点,并尝试解析内容对象的 "pi_flexform" 字段。或者你注入 flexformservice,它在 ajax 调用期间也没有加载。您必须使用 eID 机制来实现此目的。

您是否在 ext_tables.php 中声明了您的 flexforms?我通常这样做:

$extensionName = t3lib_div::underscoredToUpperCamelCase($_EXTKEY);
$pluginNames = array('pluginname1','pluginname2','...');

foreach ($pluginNames as $pluginName) {
    $pluginSignature = strtolower($extensionName) . '_'.$pluginName;

    $GLOBALS['TCA']['tt_content']['types']['list']['subtypes_excludelist'][$pluginSignature] = 'recursive';
    $GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist'][$pluginSignature] = 'pi_flexform';
    t3lib_extMgm::addPiFlexFormValue($pluginSignature, 'FILE:EXT:' . $_EXTKEY . '/Configuration/FlexForms/'.$pluginName.'.xml');
}

为什么不直接在 ajax 调用中解决它,而不是将您的插件呈现为内容对象?

plugin_yourext_ajax = PAGE
plugin_yourext_ajax {
    typeNum = 2000

    config {
        disableAllHeaderCode = 1
        xhtml_cleaning = 1
        admPanel = 0
        additionalHeaders = Content-type: text/plain
        no_cache = 1
    }

    10 = USER
    10 {
        userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
        pluginName = YourPLugin
        extensionName = YourExt
        controller = ControllerName
        vendorName = Vendor
        action = ajax

        switchableControllerActions {
            YourPlugin {
                1 = ajax
            }
        }

        persistence =< plugin.tx_your_ext.persistence
        view =< plugin.tx_your_ext.view
        update =< plugin.tx_your_ext.update
        settings < plugin.tx_your_ext.settings
    }
}

这将 bootstrap 您的分机每次通话,而不是页面呈现

我也有这个问题,后来我发现你需要使用 renderObj,它会使用 ContentObjectRenderer class。我需要 f:link 的 Flexform 值到列表模板中的详细信息页面。

所以在我的例子中,我还想要 Ajax 分页。我只是在我自己的新闻扩展的列表视图中使用了默认的 Fluid paginate 小部件。如果客户端没有 javascript 它仍然有效。所以创建炫酷的 Ajax 分页真的很容易!

typeNum 的打字错误:

ajaxPageExt = PAGE
ajaxPageExt {
    typeNum = 778

    config {
        disableAllHeaderCode = 1
        disableCharsetHeader = 1
        disablePrefixComment = 1
    }

    10 < styles.content.get
    10 {
        stdWrap.trim = 1
        select {
            where = list_type = "jpnews_list"
        }

        renderObj < tt_content.list.20.jpnews_list
    }
}

部分可能javascript:

              $('body').on('click', 'div.jpnews-list ul.f3-widget-paginator li a', (function (e) {
                    e.preventDefault();
                    paginateToPageURI = $(this).attr('href') + '&type=' + TYPO3pageType;
                    var parentDivOfNewsList = $(txJpNews).parent();
                    $(txJpNews).css('opacity', 0.4);
                    $(parentDivOfNewsList).append(spinnerHTML);
                    $.ajax({
                        type: 'POST',
                        url: paginateToPageURI,
                        data: $(this).serializeArray(),
                        success: function (data) {
                            $(parentDivOfNewsList).html(data);
                        },
                        error: function (xhr, thrownError) {
                            var msg = "<b>Sorry but there was an error, please contact us..</b><br>";
                            $(parentDivOfNewsList).html(msg + xhr.status + ' ' + thrownError);
                        }
                    });
                })

我们通过将插件(内容元素)的 uid 添加到 Ajax 请求的 URL 来解决这个问题,然后使用 [=13= 加载 flexform 配置].

在控制器中构建 URL:

$url = $this->uriBuilder->setTargetPageType(1234)->uriFor(
    'ajaxAction',
    [
        'contentUid' => (int) $this->configurationManager->getContentObject()->data['uid']
    ]
);

通过设置 flexform 设置来初始化控制器操作:

class SomeController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController
{
    protected $flexFormService;
    protected $flexformSettings = [];

    public function injectFlexFormService(\TYPO3\CMS\Extbase\Service\FlexFormService $flexFormService): void
    {
        $this->flexFormService = $flexFormService;
    }

    public function initializeAction(): void
    {
        parent::initializeAction();

        if ($this->request->hasArgument('contentUid')) {
            $recordUid = (int) $this->request->getArgument('contentUid');
            $record = TYPO3\CMS\Backend\Utility\BackendUtility::getRecord('tt_content', $recordUid, 'pi_flexform');

            if (!empty($record['pi_flexform'])) {
                $this->flexformSettings = $this->flexFormService->convertFlexFormContentToArray($record['pi_flexform']);
            }
        }
    }

    public function ajaxAction(): void
    {
        //access $this->flexformSettings;
    }
}