【问题标题】:Inject EntityManager into embedded FormTypes with Symfony2 3.0+使用 Symfony2 3.0+ 将 EntityManager 注入嵌入式 FormTypes
【发布时间】:2016-04-12 11:28:38
【问题描述】:

小问题:如何将 EntityManager 注入 symfony2 3.0+ 中的嵌入式表单类型? 注意:我提到了嵌入式表单类型,而不仅仅是父表单

长问题: 在以前版本的 Symfony2(

在以前的版本中,我在控制器中做了以下操作:

$em = $this->getDoctrine()->getManager();
$a = new A();
$form = $this->createForm(new AType($em), $a);

然后在 AType 中,我能够在构造函数中使用 $em 并继续将其传递给孩子:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('b', new BType($this->em))
    ;
}

在 BType.php 中,我会在 buildForm 中执行相同的操作以将 $em 传递给 CType。

我现在面临的问题是,为了让您在 symfony2 3.0+ 中定义嵌入式表单,您必须执行以下操作:

$form = $this->createForm(AType::class, $a);

以这种方式在没有访问控制器的情况下只给我(据我所知)一个选项,将表单定义为服务。使用此选项我有 2 个问题,一个是正如他们在文档中指定的那样,如果要在应用程序的多个部分中使用该表单,则应该使用该表单,在这种情况下,该表单将仅位于应用程序,我有那个 ABC 层次结构,以便有一个适当的数据库结构(类似于公司 > 所有者 > 员工关系)。我的另一个担忧是,如果我将表单定义为我知道我可以使用的服务:

$form = $this->createForm('servicename', $a);

在控制器中,这将注入 EntityManager,但是 BType 和 CType 呢,我如何使用 AType 作为服务将 EntityManager 注入它们?

我认为非常丑陋的最后一个想法/尝试是将 A、B、C 定义为服务并在控制器中构建表单。

【问题讨论】:

  • 您可以随时使用createForm()$options 的第三个参数并从那里传递EntityManager。您可以稍后在您的 buildForm 方法中从 $options 访问它。
  • 我必须通过 $options 的 "attr"=>array() 传递它吗?
  • em 仍应作为默认选项使用,因此传递array('em' => $entityManager) 之类的数组应该可以解决问题。
  • 你可能想多了。只需将您的表单类型定义为服务。注射将永远发生。 symfony.com/doc/current/cookbook/form/…
  • @Artamiel 如果我尝试做 $form = $this->createForm(AType::class, $a, array('em' => $em));我得到选项“em”不存在。定义的选项是:bla bla,我可以将它包含在“attr”选项中,但我真的不想弄得那么乱。我相信有更好的方法。

标签: php forms symfony dependency-injection entitymanager


【解决方案1】:

好的,我用@Cerad 解决了这个问题

app.form.a:
    class: AppBundle\Form\AType
    arguments: ["@doctrine.orm.entity_manager"]
    tags:
        - { name: form.type, alias: app.form.a }

app.form.b:
    class: AppBundle\Form\BType
    arguments: ["@doctrine.orm.entity_manager"]
    tags:
        - { name: form.type, alias: app.form.b }

app.form.c:
    class: AppBundle\Form\CType
    arguments: ["@doctrine.orm.entity_manager"]
    tags:
        - { name: form.type, alias: app.form.c }

然后在你调用的时候在控制器中:

$form = $this->createForm(AType::class, $a);

显然 Symfony2 在后台查找服务并注入依赖项,我的困惑是在使用 createForm 时必须自己调用服务之前...我没有看到任何有关此的文档..

然后,在你做的类型中:

private $em;

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

/**
 * @param FormBuilderInterface $builder
 * @param array $options
 */
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('b', BType::class)
    ;
}

如果您将 BType 定义为服务,Symfony 也会负责注入 BType 的依赖项。

感谢@Cerad!你的评论让我做了这个测试!

【讨论】:

  • 只是想指出别名标签在 Symfony 3 中消失了。没有伤害但不再做任何事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-23
  • 2011-12-15
  • 1970-01-01
  • 1970-01-01
  • 2011-05-07
  • 1970-01-01
相关资源
最近更新 更多