2

我有一个带有选择类型元素的表单。我需要用数据填充它。据我所知有3种方法。

1.控制器:

// Controller
public function myAction()
{
      $choices = ...; // create choices array
      $form = $this->createForm(new MyFormType($dm), null, array(
            'choices' => $choices,
        ));
}

// Form
class MyFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('cars', 'choice', array(
                'choices' => $options['choices']
        ));
    }
}

2.表单类+仓库

// Controller
public function myAction()
{
      $dm = $this->get('doctrine')->getManager();
      $form = $this->createForm(new MyFormType($dm));
}

// Form
class MyFormType extends AbstractType
{
    private $dm;

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

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('cars', 'choice', array(
                'choices' => $options['choices']
        ));
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $list = array();
        foreach($this->dm->getRepository('MyBundle:Cars')->findAll() as $car) {
            $list[$car->getName()] = $car->getName();
        }

        $resolver->setDefaults(array(
            'choices'        => $list,
        ));
    }
}

3.表单类+定制服务

// Controller
public function myAction()
{
      $dm = $this->get('doctrine')->getManager();
      $form = $this->createForm(new MyFormType(), null, array(
            'myservice' => $this->get('myservice'),
        ));
}

// Form
class MyFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('cars', 'choice', array(
                'choices' => $options['myservice']->getCars()
        ));
    }
}

// Service
class MyService
{
    const ENTITY_CAR = 'MyBundle:Cars';

    /** @var DocumentManager */
    private $dm;

    public function __construct(DocumentManager $dm)
    {
        $this->dm = $dm;
    }

    public function getCars()
    {
        return $this->dm->getRepository("MyBundle:Cars")->findAll();
    }
}

我会表达我的想法。

第一个选项不是最佳实践。尤其是涉及复杂逻辑的时候。控制器应该尽可能小。

2号好多了。但它会暴露实体名称,如果我决定重命名它可能会出现问题。

第三个是最好的选择,恕我直言。实体名称集中在一个地方,更好的 IDE 类型提示,集中的实体管理(搜索、保存、删除...)。主要缺点是可能的过度设计类,因为它正在负责许多读/写操作。另一方面,它可以分成几部分。

你怎么看待这件事?

4

2 回答 2

2

如果您必须在代码的其他地方重用该服务,则第三个选项很好(如果该服务与您编写的服务相比会增长,我们稍后会看到)。这样,正如您所说,该实体的“经理”是一个,并且包含自己的 repo 名称,一个 const 等等。

如果此服务仅用作通过隐藏其名称来访问您的存储库的“推动者”,我认为该解决方案仍然不像看起来那么好。
显然,如果该服务被认为具有多个持久性选项和多个检索选项(基于您选择的 ORM),那么这可能是最佳实践。

在其他情况下,我认为第二个总是更好。

除非您想忽略所有良好实践,否则第一个是不切实际的

于 2012-12-28T09:18:28.747 回答
1

我建议第四个解决方案:使用一个entity字段,因为它被设计为一个从数据库加载选项的选择字段!

这是官方文档http://symfony.com/doc/master/reference/forms/types/entity.html

以及如何使用它:

// Form
class MyFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('cars', 'entity', array(
            'class' => 'MyBundle:Cars',
            'property' => 'name',
            //Optionnal if you need to condition the selection
            'query_builder' => function(EntityRepository $er) {
                return $er->createQueryBuilder('u')->orderBy('u.username', 'ASC');
            },
        ));
    }
}
于 2012-12-28T11:12:36.267 回答