用Symfony形式分离关注点

Sti*_*vni 3 php oop domain-driven-design symfony modular-design

我最近一直在尝试使用Symfony 2表单,这对于简单表单非常有用.

但是 - 在选择框或类似的东西中使用 - 我经常需要表单中的关联实体列表.在几篇博文和Symfony文档中,他们提出了类似这样的内容......

//BlogPostType implements FormTypeInterface
public function buildForm(FormBuilderInterface $builder, array $options)
{
  $builder
  ->add('category', null, array(
    'property' => 'name',
    'query_builder' => function(EntityRepository $er) use($options) {
      return $er->createQueryBuilder('category')->orderBy('category.name', 'ASC');
    }
  );
}
Run Code Online (Sandbox Code Playgroud)

由于我非常关注域驱动设计,特别是关注点的分离,我发现很难相信将关联实体绑定到Symfony中的自定义表单类型的唯一选择是通过在自定义中查询它表格类型.

在我看来,这违反了SoC,因为表格不应该是查询.这样,表单总是采用相同的实体,但不是应该选择显示哪些实体的表单...

要求表单构建器构建表单的控制器应该将关联的对象注入自定义表单类型构造函数中......

//BlogPostType implements FormTypeInterface
public function __construct(array $categories) {
  $this->categories = $categories;
}

public function buildForm(FormBuilderInterface $builder, array $options)
{
  $builder
    ->add('category', null, array(
      'property' => 'name',
      'choices' => $this->categories
    );
}
Run Code Online (Sandbox Code Playgroud)

有谁知道如何实现这一目标?

Eln*_*mov 6

是的,您可以从控制器传递选项.只需创建一个选项而不是通过构造函数注入它,因为只有在为每个请求创建给定类型的第一个表单时才会使用构造函数.因此,如果您碰巧需要在页面上输出多个相同类型的表单,那么如果通过构造函数传递它们,它们的选择将是相同的.

当您注入可以多次重复使用而没有任何问题的服务时,通过构造函数向表单类型注入某些内容是有意义的.

文档和Web中的许多示例都违反了许多最佳实践,但是通过一些关于实践的示例来教新手更难.

  • 在你的问题中显示的方式是正确的 - 只需将一组实体传递给`entity`类型的`choices`选项. (2认同)