AJAX 事件处理器是供 AJAX 框架与服务器通信的 API 端点。它们可以响应原始数据、重定向浏览器或动态更新页面上的局部内容。
要创建 AJAX 处理器,将其定义为页面、局部或布局 PHP 部分中的 PHP 函数,或在 CMS 组件内部。处理器名称应使用onSomething模式,例如,onName。所有处理器都支持使用更新局部作为 AJAX 请求的一部分。
function onSubmitContactForm()
{
// ...
}如果在页面和布局中同时定义了两个同名处理程序,则页面处理程序将优先。组件中定义的处理程序优先级最低。
每个 AJAX 请求都应指定一个处理程序名称,无论是使用 数据属性 API 还是 JavaScript API。发出请求后,服务器将搜索所有已注册的处理程序,并定位它找到的第一个。
<!-- Attributes API -->
<button data-request="onSubmitContactForm">Go</button>
<!-- JavaScript API -->
<script> oc.ajax('onSubmitContactForm') </script>页面、布局和组件中定义的处理程序都会自动注册。如果你正在从一个局部视图(partial)内部调用处理程序,请使用 {% ajaxPartial %} Twig 标签,它会调整页面生命周期以注册其处理程序。
当 AJAX 请求在 HTML 表单标签内发生时,表单的所有输入值都可供处理程序使用。在下面的示例中,first_name 值将随请求一起发送。
<form id="myForm">
<input name="first_name" />
<button data-request="onSubmitContactForm">Go</button>
</form>JavaScript API 通过 oc.request 函数支持此逻辑。
<script> oc.request('#myForm', 'onSubmitContactForm') </script>你可以使用 input() PHP 函数来访问该变量.
function onSubmitContactForm()
{
$firstName = input('first_name');
}有时,你可能需要发起一个 AJAX 请求,其唯一目的是更新页面内容,而不需要执行任何代码。你可以为此使用 onAjax 处理器。这个处理器在任何地方都可用,而不需要编写任何代码。
<button data-request="onAjax">Do nothing</button>如果两个组件注册了相同的处理程序名称,建议在处理程序前加上组件短名称或别名。如果一个组件使用了别名mycomponent则该处理程序可以通过mycomponent::onName来定位。
<button data-request="mycomponent::onSubmitContactForm">Go</button>参见组件开发文章以了解更多信息。
如果您需要将浏览器重定向到另一个位置,请从 AJAX 处理程序返回 Redirect 响应对象。框架将在响应从服务器返回后立即重定向浏览器。带有重定向的 AJAX 处理程序示例。
function onRedirectMe()
{
return Redirect::to('http://google.com');
}AJAX 处理器返回的响应可以通过返回结构化数据充当可消费的 API。 如果 AJAX 处理器返回一个数组,你可以在 success 事件处理器中访问其元素。 返回数据对象的示例 AJAX 处理器。
function onFetchDataFromServer()
{
// Some server-side code
return [
'totalUsers' => 1000,
'totalProjects' => 937
];
}数据可以通过数据属性 API 获取。
<form data-request="onHandleForm" data-request-success="console.log(data)">与 JavaScript API 相同。
<form onsubmit="oc.request(this, 'onHandleForm', {
success: function(data) {
console.log(data);
}
}); return false"
>有时您可能希望代码在处理程序执行之前运行. 将 onInit 函数定义为 布局执行生命周期 的一部分,允许代码在每个 AJAX 处理程序之前运行.
function onInit()
{
// From a page or layout PHP code section
}您可以在 init 方法,在 CMS 组件类 中定义。
function init()
{
// From a component or widget class
}您可以使用 AjaxException 类抛出 AJAX 异常,以将响应视为错误,同时保留正常发送响应内容的能力。只需将响应内容作为异常的第一个参数传入即可。
throw new AjaxException([
'error' => 'Not enough questions',
'questionsNeeded' => 2
]);这些错误由 AJAX 框架处理。
<form data-request="onHandleForm" data-request-error="console.log(data)">JavaScript API 也是如此。
<form onsubmit="oc.request(this, 'onHandleForm', {
error: function(data) {
console.log(data);
}
}); return false"
>当抛出此异常类型时 局部视图将会更新 照常。
已分派的事件会在 AJAX 响应中触发,在请求完成后以及在局部视图更新之前。
你可以使用dispatchBrowserEvent方法从AJAX处理程序中分派JavaScript事件。此方法接受任何事件名称(第一个参数)和要传递给事件的详细变量(第二个参数),这些变量必须与JSON序列化兼容。
function onPerformAction()
{
$this->dispatchBrowserEvent('app:update-profile');
$this->dispatchBrowserEvent('app:update-profile', ['name' => 'Jeff']);
}在浏览器中,使用 addEventListener 监听 AJAX 请求完成时分派的事件。事件变量可通过 event.detail 对象获取。
addEventListener('app:update-profile', function (event) {
alert('Profile updated with name: ' + event.detail.name);
});例如,如果你想显示一个警告,提示文档已被其他用户更新,你可以向浏览器调度一个事件,并抛出一个 AjaxException 以中止该进程。
AjaxException和ValidationException是支持分发事件的终止异常。
public function onUpdate()
{
$this->dispatchBrowserEvent('app:stale-document');
throw new AjaxException;
}你可以在浏览器中使用通用监听器监听此事件。此示例在重新提交请求之前提示用户并在数据中设置了 force 标志。
addEventListener('app:stale-document', function (event) {
if (confirm('Another user has updated this document, proceed?')) {
oc.request(event.target, 'onUpdate', { data: {
force: true
}});
}
});为防止 partials 作为响应的一部分进行更新, 请在事件对象上调用 preventDefault()。
addEventListener('app:stale-document', function (event) {
event.preventDefault();
});