php Symfony 表单 - 在 CollectionType 中的子条目类型中访问实体
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9723713/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Symfony form - Access Entity inside child entry Type in a CollectionType
提问by Nick
I'm trying to access the entity for a given embedded form in the parent CollectionType
inside FormBuilder
:
我正在尝试访问CollectionType
内部父级中给定嵌入表单的实体FormBuilder
:
ParentType
父类型
Class ParentType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('children', CollectionType::class, array(
'entry_type' => ChildType::class
);
}
}
ChildType
儿童类型
class ChildType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$child = $builder->getData(); // this returns null
}
public function getDefaultOptions(array $options)
{
return array(
'data_class' => 'Vendor\Bundle\Entity\Child',
);
}
}
While this works in a normal form, $child
is being returned as null. How can I access the Child
entity inside ChildType
?
虽然这在正常形式下有效,但$child
被返回为 null。如何访问Child
里面的实体ChildType
?
回答by user1207727
The answer lies in using Event Listenerswhich listen for the PRE_SET_DATA
event.
答案在于利用事件监听器该监听PRE_SET_DATA
事件。
It will pass your closure a FormEvent
class which contains both the form and the data being bound to it.
它会给你的闭包传递一个FormEvent
包含表单和绑定到它的数据的类。
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->addEventListener(FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($builder)
{
$form = $event->getForm();
$child = $event->getData();
if ($child instanceof Child) {
// Do what ever you like with $child entity data
}
}
);
}
回答by segli
This is a more detailed solution based on user1207727.
这是基于user1207727的更详细的解决方案。
Parent Type
父类型
class FrontentStatsInputFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('records', CollectionType::class, array(
'entry_type' => FrontendStatsRecordType::class,
'allow_add' => false,
'allow_delete' => false,
'label' => null,
))
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => null
));
}
}
Child Type
儿童类型
class FrontendStatsRecordType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->addEventListener(FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($builder)
{
$form = $event->getForm();
$child = $event->getData();
if ($child instanceof StatsRecord) {
// Do what ever you like with $child entity data
// $child->getSomeValue();
$form->add('value', TextType::class);
}
}
);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\StatsRecord',
));
}
}
Create form in controller
在控制器中创建表单
public function indexAction(Request $request, InputForm $inputForm) {
$data = array();
foreach ($inputForm->getStatsTemplates() as $template) {
$statsRecord = new StatsRecord();
$data['records'][] = $statsRecord;
}
$form = $this->createForm('AppBundle\Form\FrontentStatsInputFormType', $data);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
// Get entries and persist them in the database
$records = $form->get('records')->getData();
foreach ($records as $record) {
$em->persist($record);
}
$em->flush();
return $this->redirectToRoute('frontend_index');
}
return $this->render('frontend/showInputForm.html.twig', array(
'inputForm' => $inputForm,
'form' => $form->createView(),
));
}