Sf2:FOS UserBundle:注册AJAX

时间:2016-04-03 10:17:43

标签: ajax symfony listener fosuserbundle

我正在尝试使用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> 
...

这个逻辑应该在这里还是应该覆盖控制器?我做错了什么?

1 个答案:

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

但是因为它是一个成功事件,你可能需要覆盖方法本身。