简体   繁体   English

Symfony2事件监听器问题

[英]Symfony2 Event Listener Issues

having a bit of trouble understanding Event Listeners. 难以理解事件监听器。 I have the following action in my controller 我的控制器中有以下操作

public function createAction(Request $request)
{
   try {
        $na_command = strtoupper($request->get('na_command'));
        $na_is_connecting = $request->get('na_is_connecting');

        // ==== validate (removed) ==== // 

        $em = $this->getDoctrine()->getManager();

        $alert = new AvailabilityAlert();
        $alert->setSearchCommand($na_command);
        $alert->setIsConnecting($na_is_connecting);
        $em->persist($alert);

        $em->flush();

        return new JsonResponse('Success');

    }catch (Exception $e) {
    }

}

I have a normal form (not form builder) and I create an Alert from the data and send it to my database. 我有一个普通表单(不是表单生成器),并且我从数据创建了一个警报并将其发送到我的数据库。 If successful, a Success message is sent back to my ajax. 如果成功,则将成功消息发送回我的ajax。

Here's the problem. 这是问题所在。 If the createAction is successful, I need it to send the alert to another class and do some stuff with it. 如果createAction成功,则需要它将警报发送到另一个类并对其进行处理。 So it was suggested that an Event Listener could do this for me. 因此,建议事件监听器可以为我执行此操作。 So I created a listener to test 所以我创建了一个监听器来测试

<?php

namespace Nick\AlertBundle\EventListener;

use Doctrine\ORM\Event\LifecycleEventArgs;

class AvailabilityAlertListener
{

    public function prePersist(LifecycleEventArgs $args)
    {
        die('Something is being inserted!');
    }

}

I then added it to services.yml 然后,我将其添加到services.yml

services:
    doctrine.availability_alert_listener:
        class: Nick\AlertBundle\EventListener\AvailabilityAlertListener
        arguments: []
        tags:
            - { name: doctrine.event_listener, event: prePersist }

But then how do I make the createAction listen for this event? 但是,如何使createAction侦听此事件? I am a bit lost so any advice appreciate. 我有点迷茫,所以任何建议都值得赞赏。 Essentially, at the end of createAction, I want to do something like 本质上,在createAction结束时,我想做类似的事情

include 'uapi_cron_single.php';
AddFlightsAction($alert);

But I dont want to do it like the above because it is messy. 但是我不想像上面那样做,因为它很乱。 But if createAction is successful, I need the alert to be sent to another class, so whats the best way to do this? 但是,如果createAction成功,则需要将警报发送到另一个类,那么执行此操作的最佳方法是什么?

Thanks 谢谢

First of all when you define a service without parameters you don't have to specify arguments: [] , you could simply write that 首先,当您定义不带参数的服务时,无需指定arguments: [] ,您可以简单地将其写为

services:
    doctrine.availability_alert_listener:
        class: Nick\AlertBundle\EventListener\AvailabilityAlertListener
        tags:
            - { name: doctrine.event_listener, event: prePersist }

Second, do you know that event will be fired before entity is persisted? 其次,您知道实体持久之前会触发事件吗? I suppose that's not what you want (I suppose) as you were writing about trigger an event after object is inserted into DB. 我想这不是您想要的(我想),因为您正在写有关将对象插入数据库触发事件的信息。 So you should modify your service definition as follows 因此,您应该按以下方式修改服务定义

services:
    doctrine.availability_alert_listener:
        class: Nick\AlertBundle\EventListener\AvailabilityAlertListener
        tags:
            - { name: doctrine.event_listener, event: postPersist }

and your service class 和你的服务等级

<?php

namespace Nick\AlertBundle\EventListener;

use Doctrine\ORM\Event\LifecycleEventArgs;

class AvailabilityAlertListener
{

    public function postPersist(LifecycleEventArgs $args)
    {
        die('Something is being inserted!');
    }

}

But that's not all ... 但这还不是全部...

Third, this event listener will be raised every time an object, no matter what kind (class) it has , is persisted to db. 第三, 每次将对象持久化到db时, 无论对象具有哪种类型(类),都将引发此事件侦听器。 Of course this is not what you want to. 当然,这不是您想要的。
First solution to check only for "a kind" of object beign persisted is to retrieve entity from LifecycleEventArgs argument and check with instanceof for correctness the class 仅检查持久存在的“一种”对象良性的第一个解决方案是从LifecycleEventArgs参数检索实体,并使用instanceof检查类的正确性

<?php

namespace Nick\AlertBundle\EventListener;

use Doctrine\ORM\Event\LifecycleEventArgs;

class AvailabilityAlertListener
{

    public function postPersist(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();
        if ($entity instanceof \Your\Bundle\Path\To\AvailabilityAlert) {
            /** do something **/
        }
    }

}

BUT

If you persist that kind of object only there you could also create a service on your own that not follows the logic behind event listener/subscribers and, once persisted an object of AvailabilityAlert , do some action by recalling one of his methods. 如果仅持久化此类对象,则还可以自行创建不遵循事件侦听器/订阅者背后逻辑的服务,并且一旦持久化AvailabilityAlert对象,就可以通过调用其方法之一来执行某些操作。

Returning to your question 返回您的问题

But then how do I make the createAction listen for this event? 但是,如何使createAction侦听此事件? I am a bit lost so any advice appreciate. 我有点迷茫,所以任何建议都值得赞赏。

now you should have understood that event is triggered "automatically" after object is persisted to DB. 现在您应该已经了解,在将对象持久存储到数据库之后,事件是“自动”触发的。

One more advice 另一条建议

I've noticed that you want to do 我注意到你想做

include 'uapi_cron_single.php';
AddFlightsAction($alert);

that's not correct. 那是不对的。 In Symfony2 you should use autoloading and namespacing to "include" classes from other files. 在Symfony2中,您应该使用自动加载命名空间来“包含”其他文件中的类。

I would suggest you dispatch custom event and then create custom listener. 我建议您调度自定义事件,然后创建自定义侦听器。 In Symfony2 docs there is nice entry about it: http://symfony.com/doc/current/components/event_dispatcher/introduction.html 在Symfony2文档中,有一个很好的条目: http : //symfony.com/doc/current/components/event_dispatcher/introduction.html

Correct me if i'm wrong, but this listener which you have created is an DoctrineListener. 如果我错了,请纠正我,但是您创建的此侦听器是DoctrineListener。 So it will be launched on ANY entity prePersist event. 因此它将在任何实体prePersist事件上启动。 So you would need to determine if entity that you need is persisted. 因此,您需要确定所需的实体是否持久。 But i'm not 100% sure. 但我不确定100%。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM