我有一个带有选择类型元素的表单。我需要用数据填充它。据我所知,有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();
}
}
我会表达自己的想法。
第一种选择不是最佳做法。特别是当涉及复杂的逻辑时。控制器应尽可能小。
第二个好多了。但它暴露了实体名称,如果我决定重命名它可能会出现问题。
第三是最好的选择,imho。实体名称集中在一个地方,更好的IDE类型提示,集中实体管理(搜索,保存,删除......)。主要缺点是可能过度设计的类,因为它负责许多读/写操作。另一方面,它可以分为几部分。
你怎么看?
答案 0 :(得分:2)
如果你必须在你的代码中的其他地方重用该服务,那么第三种选择是好的(如果该服务与你所编写的服务相比会增长,我们稍后会看到它)。就这样,正如你所说,那个实体的“经理”就是一个,它包含了回购的名称,一个const等等。
如果此服务仅用作通过隐藏其名称来访问您的存储库的“推送器”,我认为此解决方案看起来仍然不太好。
显然,如果认为该服务具有多个持久性选项和多个检索选项(基于您选择的ORM),那么这可能是最佳实践。
在其他情况下,我认为第二个总是更好。
除非您想忽略所有良好做法,否则第一种情况不可行
答案 1 :(得分:1)
我建议使用第四个解决方案:使用entity
字段,因为它被设计为一个选项字段,其中包含从DB加载的选项!
以下是官方文档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');
},
));
}
}