【问题标题】:Typo3 ajax call "No Template was found"Typo3 ajax 调用“未找到模板”
【发布时间】:2018-04-03 16:03:11
【问题描述】:

我想对我的控制器的一个动作进行 ajax 调用。问题是我收到错误
“抱歉,未找到请求的视图。找不到模板。无法为 xy 类中的操作 xy 解析视图”
那是我的 ajax 调用:

$.ajax({
                    type: 'POST',
                    url: '<f:uri.action action="xy" controller="XY"/>',
                    success: function(data){
                        console.log(data);
                    }
                });

这就是我的控制器的动作方法:

public function xyAction(){

    if ($this->request->hasArgument("import") && $_FILES["import"]['error'] == 0) {

        $file = $this->request->getArgument("import");
        $ext = pathinfo($file['name'], PATHINFO_EXTENSION);

        if ($ext != "csv") {
            $this->addFlashMessage('Falsche Dateiendung, es sind nur CSV-Dateien gültig.', '', \TYPO3\CMS\Core\Messaging\AbstractMessage::ERROR);
        }
       $participantsArray = $this->parseCSV($file["tmp_name"]);

        return json_encode($participantsArray);

    }else {
        $this->addFlashMessage('Keine Datei ausgewählt', '', \TYPO3\CMS\Core\Messaging\AbstractMessage::ERROR);
    }
}

parseCSV($file)方法的返回值是一个数组。

提前致谢。

【问题讨论】:

  • 有用的 cmets:1) 控制器参数绝对应该这样声明。从请求中原始读取它们是不好的做法。这有很多含义,其中包括您将如何构建到操作的链接以及它如何与缓存控件一起运行。 2) 添加 flashmessages 也不会呈现这些,除非在您的模板中完成。由于您使用 XHR,这很可能意味着您在假脱机,从不显示它们。然后重新加载页面会将它们全部发送给用户。我的建议:在响应中返回消息并将其标记为警告或错误响应。
  • 更有用的 cmets:3) 如果这块模板代码在 Fluid 模板中(看起来是这样),那么您可能无法将 JS 解析为 Fluid,例如,导致函数体为空,因此您看不到输出。 4) 请注意控制器名称是 UpperCamelCase - 您可能确实尊重这一点,但问题是在不区分大小写的文件系统(例如默认 mac-os)上可能无法检测到类名中的大小写错误。

标签: ajax typo3


【解决方案1】:

假设你出于某种原因不想使用 TYPO3 提供的 JsonView,你需要:

  • 模板(即使为空)位于预期位置。如果这不存在,那么 Extbase 甚至在你的控制器加载之前就会失败。
  • 手动创建响应内容,例如通过控制器操作中的return json_encode($var)

逻辑是:如果方法返回NULL,那么视图将被渲染。如果它返回任何其他内容(暗示:非空字符串),那么它将用作响应并且不会呈现视图。本质上:不从方法返回任何内容意味着从父控制器类调用return $this-&gt;view-&gt;render();

由于controller dispatcher无法提前知道你不想渲染View,如果不能解析模板就会失败。

这也是让您知道如何解决此问题的提示。将 View 类更改为您创建的类或不关心模板文件是否存在的类是解决此问题的另一种方法。有几种方法可以做到这一点,但最常见的是将控制器中的protected $defaultViewObjectName 设置为自定义视图的类名,如果找不到模板,则不会失败。

关于标头,您可能还需要更改响应内容类型。你如何做到这一点取决于你的具体实现——使用 TypoScript 而不是在 $this->response 中设置它可能是有意义的。

【讨论】:

  • 感谢您的详细解答!我注意到我的 if 条件是错误的,它在我不知情的情况下进入了 else 分支。
  • 请特别注意关于控制器参数的注释,这些参数应声明为控制器操作的参数,因为它们可能有助于增加关于实际提供哪些参数的混淆。强烈建议不要以这种方式直接访问请求参数,特别是不建议将它们作为不限于插件范围的全局参数传输(使用适当的参数会自动避免这种情况)。
【解决方案2】:

你可以试试

echo json_encode($participantsArray);
die();

而不是return json_encode($participantsArray);

【讨论】:

    【解决方案3】:

    这是因为在您的扩展模板文件夹中找不到xy.html 模板。因此,您需要执行以下操作。

    您需要在return json_encode() 行之后添加die() 函数。

    否则,您需要为此操作创建空白模板文件,例如 xy.html

    【讨论】:

    • 返回后无法访问 die() 方法。我想避免创建新模板。它应该只是返回到 ajax 调用模板。
    • 不幸的是,这并不能解决真正的问题,即在调用控制器操作之前,视图被要求解析模板文件。未能解析该文件会导致错误 - 这意味着您无法从控制器操作中执行任何操作都会影响它。创建空白模板文件的提示是正确的,但我在下面的回答中也提供了更多可能(而且恕我直言更好)的解决方案。
    猜你喜欢
    • 1970-01-01
    • 2018-12-21
    • 1970-01-01
    • 2016-08-30
    • 2014-02-05
    • 2010-12-20
    • 1970-01-01
    • 1970-01-01
    • 2019-07-10
    相关资源
    最近更新 更多