Ajax 和 JsonResponse
本节介绍如何使用 Joomla 组件中的 Ajax,包括如何使用 JsonResponse 提供来自服务器的响应。
本节的末尾提供了指向示例组件的链接,你可以下载并运行该示例。
你还可以使用 Joomla 模块、插件和模板中的 Ajax,下一份文档会介绍相关内容。
我们假设你熟悉使用 Ajax。
路由
当您从 JavaScript 向 Joomla 站点的 URL 发起 Ajax 调用时,Joomla 会像处理“正常”HTTP 请求一样路由 HTTP 请求;对 Ajax 请求没有特殊处理。Joomla 找到与 URL 关联的组件
,并将控制权传递给它。
因此,如果您在组件中使用 Ajax,则需要指定通过该组件路由的 URL。
如果您在模块、插件或模板中使用 Ajax,则需要将请求路由到 Joomla com_ajax 组件,该组件充当模块/插件/模板的代理。下一份文档中将对此进行介绍。
在您的组件中,您应该使用MVC 方法,并将其功能拆分为不同的控制器、模型和视图。
默认 Joomla 扩展/分发器代码使用 URL task
参数来确定要实例化的控制器类和要调用的该控制器中的方法。
例如,如果您将task
参数设置为 "ajax.divide",则默认分发器代码将实例化您的 AjaxController 并调用其divide
实例方法。
JsonResponse - 基本用法
执行获取必要数据的逻辑后,您将希望将该数据通过 Ajax 响应传回 JavaScript 代码。JsonResponse 类可以提供帮助。
其基本用法如下
use Joomla\CMS\Response\JsonResponse;
use Joomla\CMS\MVC\Controller\BaseController;
class AjaxController extends BaseController
{
public function divide()
{
try
{
// if you're using Joomla MVC classes then the Application instance is injected into
// the BaseController constructor and stored in the $app instance variable
$anyParam = $this->app->input->get('anyparam');
$result = $this->getModel('example')->calculateSomething($anyParam);
echo new JsonResponse($result);
}
catch(\Exception $e)
{
echo new JsonResponse($e);
}
}
}
在默认情况下,由模型计算得出的返回值仅传递到新的JsonResponse
对象中并写入输出。这将自动创建一个 JSON 编码的字符串,如
{"success":true,"message":null,"messages":null,"data":{"result1":1,"result2":42, ...}}
在数据字段中,您可以发送您想要的任何数组、对象或值,而成功标志会自动设置为true
。
如果模型中发生任何异常,则此异常仅直接传递到新的JsonResponse
对象中,该对象将创建以下输出
{"success":false,"message":"This is the message of the exception","messages":null,"data":null}
由于它是一个异常,因此成功标志会自动设置为false
,而这个异常消息将成为主要响应消息。
JsonResponse - 添加消息
如果您想将消息添加到您的 JsonResponse 中,则可以这么做,前提是您没有将 Exception 作为构造函数的第一个参数传递过去。
echo new JsonResponse($result, Text::_('COM_EXAMPLE_AJAX_SUCCESS'));
这将发送
{"success":true,"message":"Success message!","messages":null,"data":{"result1":1,"result2":42, ...}}
您还可以通过第三个参数 ($error
) 将错误标志设置为true
echo new JsonResponse($result, Text::_('COM_EXAMPLE_AJAX_FAILURE'), true);
这会发送
{"success":false,"message":"Failure message!","messages":null,"data":{"result1":1,"result2":42, ...}}
这样,您还可以发送一些数据,即使在出现错误的情况下也是如此。
如果你想在模板消息区中输出消息,可以使用 Joomla.renderMessages
JavaScript 函数,但你需要以这样的方式传递消息
Joomla.renderMessages({"notice": [result.message]});
因为 Joomla.renderMessages
函数需要一种 JSON 对象,其中
- 键是消息类型
- 值是字符串数组
此函数位于 media/system/js/messages.js 中,因此你需要在扩展的 joomla.asset.json 文件中将“messages”作为脚本资产的依赖项进行包括。
JsonResponse - 排队的消息
默认情况下,当你使用 JsonResponse 时,它将获得排队的消息,并将其作为 JSON 响应中的“messages”参数传递下来。
此“messages”参数的结构是 Joomla.renderMessages
所需的结构,因此在 JavaScript 中,你只需调用
Joomla.renderMessages(result.messages);
在消息区域中输出这些消息。
但是,如果你使用 Joomla.renderMessages
也来处理自己的 Ajax 成功/失败消息,那么对 Joomla.renderMessages
的第二次调用在默认情况下会删除该消息区中当前的任何消息,即,你刚刚发布在那里的消息。
为避免这种情况,在第二次调用时,你应该将 true
传递作为 Joomla.renderMessages
的第三个参数
Joomla.renderMessages(result.messages, undefined, true);
如果你不希望 JsonResponse 传递排队的消息,那么可以在你的 PHP 调用中将 JsonResponse 构造函数的第四个参数 ($ignoreMessages
) 设置为 true
echo new JsonResponse($result, Text::_('COM_EXAMPLE_AJAX_SUCCESS'), null, true);
组件示例
com_ajaxdemo 组件演示了本节中讨论的许多功能。
你可以从 com_ajaxdemo 下载 com_ajaxdemo。