Symfony 在EventSubscriberInterface中注入EntityManager

Symfony 在EventSubscriberInterface中注入EntityManager,symfony,Symfony,我已完成EventSubscriber,但我需要在中使用EntityManager。我已经把服务填好了。yml是这样的: app.subscriber.tube_dynamic_field: class: AppBundle\Form\EventListener\TubeDynamicFieldSubscriber arguments: ["@doctrine.orm.entity_manager"] class TubeDynamicFieldSubscriber imple

我已完成EventSubscriber,但我需要在中使用EntityManager。我已经把服务填好了。yml是这样的:

app.subscriber.tube_dynamic_field:
    class: AppBundle\Form\EventListener\TubeDynamicFieldSubscriber
    arguments: ["@doctrine.orm.entity_manager"]
class TubeDynamicFieldSubscriber implements EventSubscriberInterface
{
    private $em;

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

    ...
}
class TubeType extends AbstractType
{
    private $dynamicFieldSubscriber;

    public function __construct(TubeDynamicFieldSubscriber $subscriber)
    {
        $this->dynamicFieldSubscriber = $suscriber;
    }

    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
         $builder->addEventSubscriber($this->dynamicFieldSubscriber);
    }

...
}
我尝试在EventSubscriber中使用它,如下所示:

app.subscriber.tube_dynamic_field:
    class: AppBundle\Form\EventListener\TubeDynamicFieldSubscriber
    arguments: ["@doctrine.orm.entity_manager"]
class TubeDynamicFieldSubscriber implements EventSubscriberInterface
{
    private $em;

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

    ...
}
class TubeType extends AbstractType
{
    private $dynamicFieldSubscriber;

    public function __construct(TubeDynamicFieldSubscriber $subscriber)
    {
        $this->dynamicFieldSubscriber = $suscriber;
    }

    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
         $builder->addEventSubscriber($this->dynamicFieldSubscriber);
    }

...
}
最后,我在FormType中使用EventSubscriber,如下所示:

app.subscriber.tube_dynamic_field:
    class: AppBundle\Form\EventListener\TubeDynamicFieldSubscriber
    arguments: ["@doctrine.orm.entity_manager"]
class TubeDynamicFieldSubscriber implements EventSubscriberInterface
{
    private $em;

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

    ...
}
class TubeType extends AbstractType
{
    private $dynamicFieldSubscriber;

    public function __construct(TubeDynamicFieldSubscriber $subscriber)
    {
        $this->dynamicFieldSubscriber = $suscriber;
    }

    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
         $builder->addEventSubscriber($this->dynamicFieldSubscriber);
    }

...
}
但我有一个错误:

Type error: Argument 1 passed to AppBundle\Form\TubeType::__construct()
must be an instance of AppBundle\Form\EventListener
\TubeDynamicFieldSubscriber, none given
我尝试过使用它:
$builder->addEventSubscriber(new TubeDynamicFieldSuscriber())
但我又犯了一个错误:它无法恢复EntityManager

如果您知道如何在EventSubscriber中插入EntityManager:)
非常感谢。

虽然您的代码片段不是很清楚,但如果您的表单类型具有依赖项,则需要在服务容器中注册它,以便Symfony(和表单工厂)知道如何构造它

services:
    my_form_type:
        class: AppBundle\Form\TubeType
        arguments:  ["@my_event_subscriber"]
        tags: [{ name: form.type }]
但是,更好的方法可能是在表单类型中插入实体管理器:

services:
    my_form_type:
        class: AppBundle\Form\TubeType
        arguments:  ["@doctrine.orm.entity_manager"]
        tags: [{ name: form.type }]
这样,在代码中,您只需执行以下操作:

$builder->addEventSubscriber(new TubeDynamicFieldSuscriber($this->manager));

虽然代码片段不是很清楚,但如果表单类型具有依赖项,则需要在服务容器中注册它,以便Symfony(和表单工厂)知道如何构造它

services:
    my_form_type:
        class: AppBundle\Form\TubeType
        arguments:  ["@my_event_subscriber"]
        tags: [{ name: form.type }]
但是,更好的方法可能是在表单类型中插入实体管理器:

services:
    my_form_type:
        class: AppBundle\Form\TubeType
        arguments:  ["@doctrine.orm.entity_manager"]
        tags: [{ name: form.type }]
这样,在代码中,您只需执行以下操作:

$builder->addEventSubscriber(new TubeDynamicFieldSuscriber($this->manager));

你能在你的代码片段中包含类名吗?为了尊重坚实的原则,你应该“编程到一个接口,而不是实现”:我建议改变你的FormType构造函数:
public function\u构造(EventSubscriberInterface$suscriber){$this->dynamicField=$suscriber;}
这样您的类就不会与订阅者紧密耦合,您可以轻松地切换到其他订阅者。我已经编辑了我的消息并包含了类名。好吧,为了坚实的原则,我去读它。我只是从Symfony和PHP开始。谢谢。你能在你的代码片段中包含类名吗?为了尊重坚实的原则,你应该“编程到一个接口,而不是一个实现”:我建议改变你的FormType构造函数:
public function\u构造(EventSubscriberInterface$suscriber){$this->dynamicField=$suscriber;}
这样您的类就不会与订阅者紧密耦合,您可以轻松地切换到其他订阅者。我已经编辑了我的消息并包含了类名。好吧,为了坚实的原则,我去读它。我只是从Symfony和PHP开始。谢谢。我认为第二种方法比第一种更糟。最好的方法显然是将TubeType类注册为服务,为标记提供别名(与TubeType:getName()方法的返回值相同。然后,使用别名加载此表单:
$form=$this->createForm('app.forms.tube\u type',new tube());
请参阅表单类型别名在Symfony 2.8中已弃用,在Symfony 3中已删除。然后将其作为标准服务加载,
$Form=$this->createForm($this->container->get('app.forms.tube_type'),new tube()
@Van-请不要误会,但在尝试帮助之前,您可能想先了解一下Symfony。您只是把事情弄糊涂了。@Cerad我弄糊涂了什么?请告诉我,这会对我有帮助。我认为第二种方法比第一种更糟糕。最好的方法显然是将TubeType类注册为服务,为标记(与TubeType:getName()方法的返回值相同。然后,使用别名加载此表单:
$form=$this->createForm('app.forms.tube_-type',new tube());
请参阅表单类型别名在Symfony 2.8中被弃用,在Symfony 3中被删除。然后只需将其作为标准服务加载,
$form=$this->createForm即可($this->container->get('app.forms.tube_type'),new tube());
@Van-不要误会,但在尝试帮助之前,你可能想了解一下Symfony。你只是把事情弄糊涂了。@Cerad我搞糊涂了什么?请告诉我,这会对我有帮助。