2016-04-03 5 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を参照してください。

EDIT

あなたは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ユーザーイベントの1つでフォームエラーを検出することはできますか? – Brieuc

+0

私の編集を見てください:)そしてそれはイベントに完全に依存していますので、REGISTRATION_FAILUREイベントはないと思いますので、この場合はメソッドをオーバーライドする必要があります。 – chalasr

+1

明確な答えをありがとう。 – Brieuc

関連する問題