【问题标题】:Symfony access Entity Manager inside EventSubscriberSymfony 访问 EventSubscriber 中的实体管理器
【发布时间】:2016-03-20 07:56:13
【问题描述】:

我有一个雇主档案表格,我正在尝试将Employer 所在的State 与City 链接起来,这部分工作正常,但 FormType 太长了,其他地方将需要此功能所以我决定将这个逻辑移到 EventSubscriber 中,并在我需要的地方重用它。

我遇到的问题是我正在努力思考如何在 EventSubscriber 类中注入 EntityManager。

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

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

这是我的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';
    }
}

这是我的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::__construct() 必须是 Doctrine\ORM\EntityManager 的一个实例,没有给出,调用 在 /Users/shairyar/Sites/clickjobboard/src/AppBundle/Form/EmployerProfileType.php 在第 48 行并定义

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

如果在EmployerProfileType里面我替换

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

然后一切都开始正常了。

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

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

将不胜感激任何反馈。

【问题讨论】:

  • 这是绝对正常的行为。您正在自己创建订阅者的实例而不是请求它 - 因此您得到了例外。 app.form.location 是您的服务的 ID,但您没有使用它。
  • @Artamiel 谢谢,是的,我明白了,所以如何use :)

标签: php doctrine-orm dependency-injection symfony


【解决方案1】:

我认为您需要将您的 AddStateFieldSubscriber 标记为 kernel.event_subscriber。

然后根本不需要表单内的绑定。

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

【讨论】:

  • 谢谢,有什么代码可以分享一下如何在事件订阅者中检查正确的表单吗?
  • 对不起,我自己从来没有这样做过。 $event->getForm->getName() ?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-01
  • 1970-01-01
  • 2018-09-15
  • 1970-01-01
相关资源
最近更新 更多