简体   繁体   English

EventSubscriber中的Symfony访问实体管理器

[英]Symfony access Entity Manager inside EventSubscriber

I have an Employer profile form and I am trying to link the State where Employer is located at with a City this part is working alright but the FormType got so long and this feature will be required at other places of the website so I decided to move this logic inside an EventSubscriber and reuse it where ever I need it. 我有一份雇主资料表格,我正在尝试将Employer所在的StateCity这部分工作正常,但FormType有这么长时间,这个功能将在网站的其他地方需要,所以我决定搬家这个逻辑在EventSubscriber中,并在我需要的地方重用它。

Problem I am having is I am trying to wrap my head around how to inject EntityManager inside the EventSubscriber class. 我遇到的问题是,我试图将自己的头放在如何在EventSubscriber类内注入EntityManager

I know I can add the following code inside my services.yml and that should do it buts its not working. 我知道我可以在我的services.yml添加以下代码,但应该这样做,但是无法正常工作。

app.form.location:
    class: AppBundle\Form\EventListener\AddStateFieldSubscriber
    arguments: ['@doctrine.orm.entity_manager']
    tags:
        - { name: kernel.event_subscriber }

This is my EmployerProfileType where I am calling my addEventSubscriber which is AddStateFieldSubscriber() 这是我的EmployerProfileType ,我在其中调用我的addEventSubscriber ,即AddStateFieldSubscriber()

class EmployerProfileType extends AbstractType
{
    protected $em;

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

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('firstName', TextType::class)
            ->add('lastName', TextType::class)
            ->add('companyName', TextType::class)
            ->add('companyProfile', TextareaType::class)
            ->add('companyLogo', FileType::class, array(
                'data_class' => null
            ));
        $builder->addEventSubscriber(new AddStateFieldSubscriber());

    }


    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\EmployerProfile',

        ));
    }


    public function getName()
    {
        return 'app_bundle_emp_profile_type';
    }
}

This is my AddStateFieldSubscriber class where I need access to EntityManager 这是我的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);
    }
}

The error I get is 我得到的错误是

Catchable Fatal Error: Argument 1 passed to AppBundle\\Form\\EventListener\\AddStateFieldSubscriber::__construct() must be an instance of Doctrine\\ORM\\EntityManager, none given, called in /Users/shairyar/Sites/clickjobboard/src/AppBundle/Form/EmployerProfileType.php on line 48 and defined 可捕获的致命错误:传递给AppBundle \\ Form \\ EventListener \\ AddStateFieldSubscriber :: __ construct()的参数1必须是Doctrine \\ ORM \\ EntityManager的实例,没有给出,在/ Users / shairyar / Sites / clickjobboard / src / AppBundle / Form中调用/EmployerProfileType.php在第48行并已定义

I am injecting EntityManager via service then why do I get this error? 我通过服务注入EntityManager然后为什么我会收到此错误?

If inside EmployerProfileType I replace 如果在EmployerProfileType里面我替换了

$builder->addEventSubscriber(new AddStateFieldSubscriber(); to $builder->addEventSubscriber(new AddStateFieldSubscriber($this->em)); $builder->addEventSubscriber(new AddStateFieldSubscriber(); to $builder->addEventSubscriber(new AddStateFieldSubscriber($this->em));

then things start working fine. 事情开始正常。

I thought in Symfony we are supposed to inject the dependencies by creating services? 我以为在Symfony中我们应该通过创建服务来注入依赖项? So how can I inject EntityManager inside my AddStateFieldSubscriber() class 那么如何将EntityManager注入AddStateFieldSubscriber()类中

What am i doing wrong? 我究竟做错了什么? may be I am over thinking about it. 可能是我在思考它。

Will appreciate any feedback. 将不胜感激任何反馈。

I think you need to tag your AddStateFieldSubscriber as kernel.event_subscriber. 我认为您需要将AddStateFieldSubscriber标记为kernel.event_subscriber。

Then the binding inside the form in not needed at all. 然后,根本不需要表单内的绑定。

Instead you need to check for the correct form, and jump out of the event listener method if the form is not one of your forms using that subscriber, since the Event would be triggered on any form then, not only the EmployerProfileType form. 相反,您需要检查正确的表单,如果表单不是使用该订阅者的表单之一,则跳出事件侦听器方法,因为事件将在任何表单上触发,而不仅仅是EmployerProfileType表单。

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

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