Forms Symfony2从集合创建表单
我需要创建一个表单来编辑实体列表。这与经典用例(以及我发现的所有示例)不同,在经典用例中,我们有一个作为嵌套实体的实体 在我的情况下,我想使用:Forms Symfony2从集合创建表单,forms,symfony,collections,types,Forms,Symfony,Collections,Types,我需要创建一个表单来编辑实体列表。这与经典用例(以及我发现的所有示例)不同,在经典用例中,我们有一个作为嵌套实体的实体 在我的情况下,我想使用: $form = $this->get('form.factory')->create( new MyType(), mycollectionofobjects ); 因此表单需要处理一个对象集合(在我的例子中是一个推进集合) 在典型情况下,我们可以使用: $formBuilder->add(
$form = $this->get('form.factory')->create(
new MyType(),
mycollectionofobjects
);
因此表单需要处理一个对象集合(在我的例子中是一个推进集合)
在典型情况下,我们可以使用:
$formBuilder->add(
'getTheCollection',
"collection", etc...
因此,从主对象开始,子窗体是使用getTheCollection的数据构建的,但是,如果没有主实体,它就无法工作。我在这种情况下使用的解决方案如下
- 当然,创建一个不会持久化到DB的实体,并且只表示一个容器。差不多
use Doctrine\Common\Collections\ArrayCollection; class YourTypeCollector { protected $your_type_colletion; public function __construct() { $this->your_type_colletion = new ArrayCollection(); } public function setYourTypeCollection(ArrayCollection $yourTypeCollection) { $this->your_type_collection = $yourTypeCollection } public function getYourTypeCollection() { return $this->your_type_collection; } }
- 创建
YourTypeCollectorForm
class YourTypeCollectorFormType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add('your_type_collection', 'collection', array( 'type' => new YourTypeType() ); } public function getName() { return 'your_type_collector_form'; } public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setDefaults(array( 'data_class' => 'Path\To\Your\Type\Collector', 'cascade_validation' => true, //!Important )); } }
- 将其实例化到控制器中,并像“普通”其他具有集合的表单一样使用它
$your_type_colletor = new YourTypeCollector(); $your_type_collector->setYourTypeCollection(//an array collection here); $form = $this->createForm(new YourTypeCollectorType());
我不确定这是否是解决这个问题的最佳方法,但我确信这是可行的,因为我目前将其用于我的旧项目中另一种可能性可能是这样的(据信是适应性的): 如果存在一个名为Collection的实体,该实体包含一组对象,请创建一个表单视图,以允许编辑所有(或选定)对象 1) 为单个对象创建表单类型:
class CollectionType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('object')
;
}
public function getName()
{
return 'collection';
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'YourBundle\Entity\Collection',
));
}
2) 为一组对象创建表单类型
class ObjectsType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('objects', 'collection', ['type' => new CollectionType(),
])
))
;
}
3) 在控制器中实例化窗体
public function editObjectsAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$objects = $em->getRepository("YourBundle:Collection")->findAll();
$form = $this->createForm(new ObjectsType(), array('objects' => $objects));
...
}
[希望我已经正确推广了此解决方案的使用!]
对于一个“真实世界”的应用程序,请参见。谢谢,我是用一个只有方法“getChild”的伪根对象这样做的,然后当我创建子窗体时,我给了参数“child”,仅此而已。我不确定这是不是最好的方法,我很好奇是否有更好(更“漂亮”)的解决方案?你可以使用数组而不是创建一个特殊的集合对象。@Cerad:我很确定你在这里展示的方法,这是显而易见的。但是,正如我在这里所说的,这是我在老项目中使用的一个解决方案,对于这个答案,我只是复制/粘贴/改编到这里:)是的。我想不久前我也做了同样的事情,直到我意识到数组可以很好地工作。@Cerad:你知道这个过程,不是吗?问题->工作代码->良好代码->完美代码:)