Php EventSubscriber内的Symfony access实体管理器

Php EventSubscriber内的Symfony access实体管理器,php,doctrine-orm,dependency-injection,symfony,Php,Doctrine Orm,Dependency Injection,Symfony,我有一个雇主简介表格,我正试图将州雇主所在地与城市链接起来,这部分工作正常,但表格类型太长,网站的其他地方也需要此功能,所以我决定将此逻辑移到EventSubscriber中,并在其他地方重新使用它只要我需要它 我遇到的问题是,我正试图思考如何在EventSubscriber类中注入EntityManager 我知道我可以在我的服务中添加以下代码。yml应该可以,但它不起作用 app.form.location: class: AppBundle\Form\EventListener\A

我有一个雇主简介表格,我正试图将
雇主所在地
城市
链接起来,这部分工作正常,但表格类型太长,网站的其他地方也需要此功能,所以我决定将此逻辑移到EventSubscriber中,并在其他地方重新使用它只要我需要它

我遇到的问题是,我正试图思考如何在
EventSubscriber
类中注入
EntityManager

我知道我可以在我的
服务中添加以下代码。yml
应该可以,但它不起作用

app.form.location:
    class: AppBundle\Form\EventListener\AddStateFieldSubscriber
    arguments: ['@doctrine.orm.entity_manager']
    tags:
        - { name: kernel.event_subscriber }
这是我的
EmployeerProfileType
,我在这里调用我的
AddEventsSubscriber
,它是
AddStateFieldSubscriber()

这是我的
AddStateFieldSubscriber
类,我需要在其中访问
EntityManager

class AddStateFieldSubscriber implements EventSubscriberInterface
{

    protected $em;

    function __construct(EntityManager $em)
    {
        $this->em = $em;
    }

    public static function getSubscribedEvents()
    {
        // Tells the dispatcher that you want to listen on the form.pre_set_data
        // event and that the preSetData method should be called.
        return array(
            FormEvents::PRE_SET_DATA => 'onPreSetData',
            FormEvents::PRE_SUBMIT => 'onPreSubmit'
            );
    }
    protected function addElements(FormInterface $form, States $province = null)
    {
        // Remove the submit button, we will place this at the end of the form later
        // Add the province element
        $form->add('state', EntityType::class, array(
                'data' => $province,
                'placeholder' => 'provide_state',
                'class' => 'AdminBundle\Entity\States',
                'mapped' => false)
        );
        // Cities are empty, unless we actually supplied a province
        $cities = array();
        if ($province) {
            // Fetch the cities from specified province
            $repo = $this->em->getRepository('AdminBundle:Cities');
            $cities = $repo->findByStates($province, array('name' => 'asc'));
        }
        // Add the city element
        $form->add('city', EntityType::class, array(
            'placeholder' => 'provide_state_first',
            'class' => 'AdminBundle\Entity\Cities',
            'choices' => $cities,
        ));

    }
    function onPreSubmit(FormEvent $event) {
        $form = $event->getForm();
        $data = $event->getData();

        // Note that the data is not yet hydrated into the entity.
        $province = $this->em->getRepository('AdminBundle:States')->find($data['state']);
        $this->addElements($form, $province);
    }
    function onPreSetData(FormEvent $event) {
        $account = $event->getData();
        $form = $event->getForm();

        // We might have an empty account (when we insert a new account, for instance)
        $province = $account->getCity() ? $account->getCity()->getStates() : null;
        $this->addElements($form, $province);
    }
}
我得到的错误是

可捕获致命错误:参数1传递给 AppBundle\Form\EventListener\AddStateFieldSubscriber::\uu构造() 必须是条令\ORM\EntityManager的实例,未给定,已调用 在里面 /Users/shairyar/Sites/clickjobboard/src/AppBundle/Form/employeerprofiletype.php 在第48行,定义了

我正在通过服务注入
EntityManager
,为什么会出现此错误

如果在
employeerprofiletype
I内部,则更换

$builder->addEventSubscriber(新的AddStateFieldSubscriber();
$builder->addEventSubscriber(新的AddStateFieldSubscriber($this->em));

然后事情开始好转

我认为在Symfony中,我们应该通过创建服务来注入依赖项?那么我如何才能在我的
AddStateFieldSubscriber()类中注入
EntityManager

我做错了什么?可能是我想得太多了


非常感谢您的反馈。

我想您需要将您的
AddStateFieldSubscriber
标记为kernel.event\u订户

那么表单中的绑定就根本不需要了


相反,您需要检查正确的表单,如果表单不是使用该订阅服务器的表单,则跳出事件侦听器方法,因为事件将在任何表单上触发,而不仅仅是EmployerProfileType表单。

我想您需要将
AddStateFieldSubscriber
标记为kernel.event\u订阅服务器

那么表单中的绑定就根本不需要了


相反,您需要检查表单是否正确,如果表单不是使用该订阅服务器的表单,则跳出事件侦听器方法,因为事件将在任何表单上触发,而不仅仅是EmployerProfileType表单。

这是绝对正常的行为。您是在自己创建订阅服务器的实例,而不是创建订阅服务器的实例请求它-因此你得到了一个例外。
app.form.location
是你服务的ID,但你没有使用它。@Artamiel谢谢,是的,我理解,所以如何
使用它:)这是绝对正常的行为。您自己创建了订阅者的一个实例,而不是请求它——因此出现了异常
app.form.location
是您服务的ID,但您没有使用它。@Artamiel谢谢,是的,我理解,所以如何
使用它:)谢谢,关于如何在活动订阅服务器中检查正确的表单,您可以分享一些代码吗?很抱歉,我自己从来没有这样做过$event->getForm->getName()?谢谢,关于如何在事件订阅服务器中检查正确的表单,您可以分享一些代码吗?很抱歉,我从来没有这样做过$事件->获取表单->获取名称()?
class AddStateFieldSubscriber implements EventSubscriberInterface
{

    protected $em;

    function __construct(EntityManager $em)
    {
        $this->em = $em;
    }

    public static function getSubscribedEvents()
    {
        // Tells the dispatcher that you want to listen on the form.pre_set_data
        // event and that the preSetData method should be called.
        return array(
            FormEvents::PRE_SET_DATA => 'onPreSetData',
            FormEvents::PRE_SUBMIT => 'onPreSubmit'
            );
    }
    protected function addElements(FormInterface $form, States $province = null)
    {
        // Remove the submit button, we will place this at the end of the form later
        // Add the province element
        $form->add('state', EntityType::class, array(
                'data' => $province,
                'placeholder' => 'provide_state',
                'class' => 'AdminBundle\Entity\States',
                'mapped' => false)
        );
        // Cities are empty, unless we actually supplied a province
        $cities = array();
        if ($province) {
            // Fetch the cities from specified province
            $repo = $this->em->getRepository('AdminBundle:Cities');
            $cities = $repo->findByStates($province, array('name' => 'asc'));
        }
        // Add the city element
        $form->add('city', EntityType::class, array(
            'placeholder' => 'provide_state_first',
            'class' => 'AdminBundle\Entity\Cities',
            'choices' => $cities,
        ));

    }
    function onPreSubmit(FormEvent $event) {
        $form = $event->getForm();
        $data = $event->getData();

        // Note that the data is not yet hydrated into the entity.
        $province = $this->em->getRepository('AdminBundle:States')->find($data['state']);
        $this->addElements($form, $province);
    }
    function onPreSetData(FormEvent $event) {
        $account = $event->getData();
        $form = $event->getForm();

        // We might have an empty account (when we insert a new account, for instance)
        $province = $account->getCity() ? $account->getCity()->getStates() : null;
        $this->addElements($form, $province);
    }
}