我正在尝试使用AJAX注册用户。
我在FOSUserEvents::REGISTRATION_SUCCESS
所以我试图知道是否已经发出了AJAX请求,但我客户端的响应并不能让我满意。
这里是我的事件监听器,请注意发送的响应是一个测试,所以当然不应该有“其他”条件。
<?php
namespace SE\AppBundle\EventListener;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Event\FormEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\RequestStack;
/**
* Ajax listener on FOS UserBundle registration
*/
class RegistrationListener implements EventSubscriberInterface
{
private $router;
public function __construct(RequestStack $RequestStack)
{
$this->requestStack = $RequestStack;
}
/**
* {@inheritDoc}
*/
public static function getSubscribedEvents()
{
return array(
FOSUserEvents::REGISTRATION_SUCCESS => 'onRegistrationSuccess'
);
}
public function onRegistrationSuccess()
{
$request = $this->requestStack->getCurrentRequest();
if ($request->isXmlHttpRequest()) {
$array = array( 'success' => true ); // data to return via JSON
$response = new Response( json_encode( $array ) );
$response->headers->set( 'Content-Type', 'application/json' );
return $response;
}
else{
$array = array( 'success' => false ); // data to return via JSON
$response = new Response( json_encode( $array ) );
$response->headers->set( 'Content-Type', 'application/json' );
return $response;
}
}
}
services.yml
:
se.app.listener.registration:
class: SE\AppBundle\EventListener\RegistrationListener
arguments: ["@request_stack"]
tags:
- { name: kernel.event_subscriber }
的javascript:
// Submit the request
$.ajax({
type : 'POST',
url : url,
data : data,
success : function(data, status, object) {
console.log('success');
console.log(data);
},
error: function(data, status, object){
console.log('error');
console.log(data);
}
});
首先,奇怪的是它处于错误状态。
console.log
(数据)返回注册成功页面的DOM:
...
<p>Congrats brieuc.tribouillet7777@gmail.com, your account is now activated.</p>
...
这个逻辑应该在这里还是应该覆盖控制器?我做错了什么?
答案 0 :(得分:3)
由于REGISTRATION_SUCCESS
事件的级别,您无法直接从EventListener
返回回复。
您需要抓住FormEvent
并修改其回复
让我们把它作为参数传递:
class RegistrationListener implements EventSubscriberInterface
{
// ...
public function onRegistrationSuccess(FormEvent $event)
{
$request = $this->requestStack->getCurrentRequest();
// Prepare your response
if ($request->isXmlHttpRequest()) {
$array = array( 'success' => true ); // data to return via JSON
$response = new Response( json_encode( $array ) );
$response->headers->set( 'Content-Type', 'application/json' );
} else {
$array = array( 'success' => false ); // data to return via JSON
$response = new Response( json_encode( $array ) );
$response->headers->set( 'Content-Type', 'application/json' );
}
// Send it
$event->setResponse($response);
}
}
它应该有用。
注意此事件存在无法修改响应的问题 如果出现问题,您需要在事件订阅中设置低优先级:
public static function getSubscribedEvents()
{
return [
FOSUserEvents::REGISTRATION_SUCCESS => [
['onRegistrationSuccess', -10],
],
];
}
请参阅#1799。
修改强>
注意您应该使用JsonResponse而不是json_encode
数据,并手动设置Content-Type
。
要抓取表单本身及其最终错误,您可以执行以下操作:
public function onRegistrationSuccess(FormEvent $event)
{
$form = $event->getForm();
if (count($validationErrors = $form->getErrors()) == 0) {
return $event->setResponse(new JsonResponse(['success' => true]));
}
// There is some errors, prepare a failure response
$body = [];
// Add the errors in your response body
foreach ($validationErrors as $error) {
$body[] = [
'property' => $error->getPropertyPath() // The field
'message' => $error->getMessage() // The error message
];
}
// Set the status to Bad Request in order to grab it in front (i.e $.ajax({ ...}).error(...))
$response = new JsonResponse($body, 400);
$event->setResponse($response);
}
但是因为它是一个成功事件,你可能需要覆盖方法本身。