【问题标题】:symfony 3 - how to add a eventsubscriber as a service in a formsymfony 3 - 如何在表单中添加事件订阅者作为服务
【发布时间】:2018-04-19 18:36:06
【问题描述】:
在我的应用程序中,我为表单中的 onPostSubmit 事件创建了一个侦听器。
我创建了一个实现 EventSubscriberInterface 的新类。
在builderForm中,我像这样添加了evnet订阅者:
->addEventSubscriber(new MyNewListener())
一切都运行良好,但不是我想要的......
在我的监听器中,我需要实体管理器来查询数据库。
我找到的第一个解决方案是通过选项在表单中添加实体管理器,并通过构造函数将其传递给监听器。代码现在是:
->addEventSubscriber(new MyNewListener($options['entity_manager']))
此解决方案有效,但我不想这样使用它,我更喜欢使用服务并在服务定义中添加实体管理器。
那么,我的问题是:如何将监听器声明为服务(并传递实体管理器)以及如何在表单声明中调用它?
感谢您的帮助。
【问题讨论】:
标签:
forms
symfony
events
service
listener
【解决方案1】:
您可以将您的表单定义为容器中的服务,就像 Cerad 在他的评论中提到的那样。
由于您使用的是 Symfony 3,您可以选择使用 autowire: true 配置服务,或者手动声明您的参数。然后在您的 FormType 中,您可以将这些类属性传递给您的订阅者类。当您将表单定义为服务时,请务必使用form.type 对其进行标记。下面是示例代码。
Services.yml
services:
your.form.type:
class: EventsBundle\Form\MarketerType
autowire: true # this is not needed if using arguments
arguments: [ '@doctrine.orm.entity_manager' ] # this is not needed if using autowire
tags:
- { name: form.type }
FormType.php
<?php
namespace EventsBundle\Form;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Form\AbstractType;
...
class FormType extends AbstractType
{
/** @var EntityManager */
private $em;
public function __construct(EntityManager $em)
{
$this->em = $em;
}
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
...
$builder->addEventSubscriber(new YourNewListener($this->em));
}
...
然后,为了安全起见,您需要清除应用程序缓存。我希望这会有所帮助!
【解决方案2】:
只需将您的订阅者视为一项服务。
Yml 配置。如果您已自动连接所有类,则可以节省 autowire:true:
services:
My\Form\Type:
autowire: true
tags:
- { name: form.type }
My\Form\Listener\MyNewListener:
autowire: true
表单类:
...
class MyForm extends AbstractType
{
/**
* @var MyNewListener
*/
private $listener;
/**
* @param MyNewListener $listener
*/
public function __construct(MyNewListener $listener)
{
$this->listener = $listener;
}
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
...
$builder->addEventSubscriber($this->listener);
}
}