我需要创建一个表单类型,该类型将创建某个实体的多个记录。
我想创建一个父窗体类型,然后在里面添加一个集合。这个父类型没有绑定到任何实体,但子类型绑定到了。问题是,当我处理请求时,我会得到一个空的数据对象。
这是我的父母类型:
class ChallengeCollectionType extends AbstractType {
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('email_invitations', CollectionType::class, [
'entry_type' => EmailInvitationType::class
]);
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'csrf_protection' => false
));
}
}
我的孩子类型:
class EmailInvitationType extends AbstractType {
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('email', EmailType::class);
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => Challenge::class,
'csrf_protection' => false
));
}
}
以下是我在Controller中处理数据的方式:
public function inviteEmailAction(Request $request){
$form = $this->createForm(ChallengeCollectionType::class);
$form->handleRequest($request);
dump($form->getData());
dump($form->get('email_invitations')->getData());
die();
}
我在POST请求中提交数据(这是API,没有HTML表单),如下所示:
challenge_collection[email_invitations][0][email] = "email@address.com"
challenge_collection[email_invitations][1][email] = "address@email.com"
控制器为所有转储返回空[]。
事实上,我已经找到了一个变通方法,但看起来很糟糕:
$data = ['email_invitations' => [new Challenge(), new Challenge()]];
$form = $this->createForm(ChallengeCollectionType::class, $data);
$form->handleRequest($request);
这将起作用,所以我必须发送一个Entity类型的空对象数组来处理请求。
甚至是这样:
$data = ['email_invitations' => []];
if(!empty($request->request->get('challenge_collection'))){
if(!empty($request->request->get('challenge_collection')['email_invitations'])){
for($i = 0; $i < count($request->request->get('challenge_collection')['email_invitations']); $i ++){
$data['email_invitations'][] = new Challenge();
}
}
}
应该有更好的方法,请帮我找到它。
您应该尝试在集合字段类型中使用allow_add
和allow_delete
选项。参见收集字段类型文档
此外,这对于父实体和子实体具有mapped-by
关联非常重要,这将使您在控制器中的ArrayCollection
对象中获得子对象。
此外,如果您想根据请求自动保存/删除它们,则需要实现"by_reference false and set association with
cascade persistent and
cascade remove"。
我已经在API中多次使用collection
字段类型,它的工作非常有魅力。如果你需要进一步的解释,请告诉我。
也许您应该在控制器中尝试以下操作:
$invitations = $this->getDoctrine()->getRepository('yourInvitationEntityClass')->findAll());
$form = $this->createForm(ChallengeCollectionType::class, $invitations );
你可以在这里找到解释:
http://symfony.com/doc/current/cookbook/form/form_collections.html
一个表单包含一个实体的所有行