我必须在Symfony项目中管理表单的答案。我目前有4个实体:
在MyFormType类中,我具有类型QuestionsBlockType的CollectionType属性。确实,我想在表单中动态添加/删除问题块。但是每个问题块都必须包含基于模型问题实体的问题。
例如,如果我的数据库中有5个QuestionModel条目,则每次添加一个问题块时,我希望创建5个新问题。当我在QuestionsBlock构造函数中传递问题时,每次在CollectionType中创建新条目时,我都会尝试使用参数创建一个新的QuestionsBlock实例。
要实现这一点,我在文档上看到可以使用CollectionType的prototype_data属性:https://symfony.com/doc/current/reference/forms/types/collection.html#prototype-data
使用此选项,子类型将显示在屏幕上,但是当我提交表单时似乎没有创建对象。
因此,我看到我可以使用QuestionBlockType中的empty_data属性创建具有以下参数的实例:https://symfony.com/doc/current/form/use_empty_data.html
但是似乎还不够。我知道保存表单时会执行“ empty_data代码”,但出现错误“函数的参数太少了问题:: __ construct(),传递了0个,恰好是1个。”因此,我猜想QuestionsBlock构造函数在Submit时被调用,但我不明白为什么它试图创建没有args的Question实例。
我应该做什么?
控制器
public function addAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$models = $em->getRepository(QuestionModel::class)->findAll();
$myForm = new MyForm();
$form = $this->createForm(MyFormType::class, $myForm, ['models' => $models]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em->persist($myForm);
$em->flush();
return $this->redirectToRoute('...');
}
return $this->render('Admin/MyForm/add_edit.html.twig', array(
'myForm' => $myForm,
'models' => $models,
'form' => $form->createView()
));
}
MyForm实体
/**
* MyForm
*
* @ORM\Table(name="my_form")
* @ORM\Entity()
*/
class MyForm
{
/**
* @ORM\OneToMany(targetEntity="QuestionsBlock", mappedBy="myForm", cascade={"persist", "remove"})
*/
private $questionsBlocks;
...
}
问题阻止实体
/**
* QuestionsBlock
*
* @ORM\Table(name="questions_block")
* @ORM\Entity()
*/
class QuestionsBlock
{
/**
* @ORM\OneToMany(targetEntity="question", mappedBy="questionsBlock", cascade={"persist", "remove"})
*/
private $questions;
public function __construct($models)
{
$this->questions = new ArrayCollection();
foreach ($models as $model) {
$this->addQuestion(new Question($model));
}
}
...
}
问题实体
/**
* Question
*
* @ORM\Table(name="question")
* @ORM\Entity()
*/
class Question
{
/**
* @ORM\ManyToOne(targetEntity="ModelQuestion")
*/
private $modelQuestion;
public function __construct($modelQuestion)
{
$this->modelQuestion = $modelQuestion;
}
...
}
我的表格类型
class MyFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$models = $options['models'];
$builder
->add('questionsBlocks', CollectionType::class, array(
'entry_type' => QuestionsBlockType::class,
'required' => true,
'allow_add' => true,
'allow_delete' => true,
'delete_empty' => true,
'by_reference' => false,
'prototype_data' => (new QuestionBlock($models))
))
->add('save', SubmitType::class, array(
'label' => 'Enregistrer'
))
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => MyForm::class,
'models' => []
));
}
}
问题块类型
class QuestionsBlockType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('questions', CollectionType::class, array(
'entry_type' => QuestionType::class,
'required' => true,
'allow_add' => true,
'allow_delete' => true,
'delete_empty' => true,
'by_reference' => false
))
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'empty_data' => function (FormInterface $form) {
return new QuestionsBlock($form->getRoot()->getConfig()->getOption('models'));
},
'data_class' => QuestionsBlock::class
));
}
}
问题类型
class QuestionType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title', TextType::class, array(
'label' => 'Titre',
'required' => false
))
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => Question::class
));
}
}