2016-04-03 63 views
4

我正在尝试使用AJAX注册用户。Sf2:FOS UserBundle:注册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 [email protected], your account is now activated.</p> 
... 

那么,这是否逻辑应该在这里或者我应该重写控制器?我究竟做错了什么?

回答

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); 
} 

但因为它是一个成功的事件,您可能需要重写方法本身。

+0

太棒了!因此,最好使用事件侦听器,而不是重写方法,不是吗?你是否能够在其中一个fos用户事件中捕获表单错误? – Brieuc

+0

看看我的编辑:),它完全取决于事件,我认为没有REGISTRATION_FAILURE事件,因此您可能需要重写此方法。 – chalasr

+1

谢谢你的明确答案。 – Brieuc