【问题标题】:What is the best practice for building choices list建立选择列表的最佳实践是什么
【发布时间】:2012-12-28 09:02:59
【问题描述】:

我有一个带有选择类型元素的表单。我需要用数据填充它。据我所知,有 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();
    }
}

我会表达我的想法。

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

第二个更好。但是它会暴露实体名称,如果我决定重命名它可能会出现问题。

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

你怎么看?

【问题讨论】:

    标签: php symfony symfony-forms


    【解决方案1】:

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

    但是

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

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

    第一个是不切实际的,除非你想忽略所有好的做法

    【讨论】:

      【解决方案2】:

      我建议第四个解决方案:使用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');
                  },
              ));
          }
      }
      

      【讨论】:

      • 在这种解决方案的情况下,我无法为选项列表设置值。 name 属性仅定义标签,索引用作不适合我的值。
      • 您需要什么作为选项的值和文本?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-13
      • 1970-01-01
      • 2011-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多