同一字段多次Symfony 4形式
Same field multiple times Symfony 4 form
我有一个实体 Report,它包含许多 Answers。
class Report
{
/**
* @ORM\OneToMany(targetEntity="App\Entity\Answer", mappedBy="report")
*/
private $answers;
...
}
class Answer
{
/**
* @ORM\ManyToOne(targetEntity="Report", inversedBy="answers")
*/
private $report;
...
}
我在 ReportType 中手动添加问题(我知道这不是最好的方法,但问题永远不会改变,我只对答案感兴趣。)
class ReportAnswersType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('answers', ChoiceType::class, array(
'label' => 'Room state',
'multiple' => false, 'expanded' => false,
'choices' => array('OK' => 'OK', 'NG' => 'NG', 'NP' => 'NP',),
))
->add('answers', IntegerType::class, array(
'label' => 'Temperature',
))
->add('answers', ChoiceType::class, array(
'label' => 'Is it good?',
'multiple' => false, 'expanded' => false,
'choices' => array('YES' => 'YES', 'NO' => 'NO',),
))
...
}
->add('save', SubmitType::class);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => Report::class,
));
}
我想做的是生成一个包含 3 个问题的表单,并将每个答案插入数据库。
但是呈现的表格只显示最后一个问题(因为每个 ->add('answers', ...) 我替换最后一个添加的)。
我尝试了不同的解决方案来解决这个问题:
- 遵循 How to Embed a Collection of Forms 上的文档,其中包括将每个答案(带有问题标签)添加到 Controller 中的 Report,然后呈现 ReportType。问题是我的每个问题都有不同的类型(选择、文本、整数...),我不知道如何单独定制它们。
- 我也尝试在我的 ReportType 中做 this,但它只显示最后添加的问题。
感谢任何帮助,谢谢!
可以使用Entity-Attribute-Value模型来解决这个问题。我建议使用 sidus/eav-model-bundle。这将是一项大量的工作,但您会学到很多东西。使用 EAV 模型,您可以有 N 个问题和答案。
我想不出使用简单的表单类型来解决这个问题。
我设法让它工作了。最后我按照 How to Embed a Collection of Forms.
上的说明进行操作
为了让它工作,我将字段 question 和 questionType 添加到我的 Answer 实体中。在 AnswerType.php 上,我每次都会检查它是什么类型的问题,然后根据它创建答案的类型。它看起来像这样:
$builder->addEventListener(FormEvents::POST_SET_DATA, function ($event) {
$builder = $event->getForm();
$answer = $event->getData();
$questionType = $answer->getQuestionType();
$question = $answer->getQuestion();
if ($questionType == 1){
$builder->add('answer', ChoiceType::class, array(
'label' => $question,
'multiple' => false, 'expanded' => false,
'choices' => array('OK' => 'OK', 'NG' => 'NG', 'NP' => 'NP',),
));
}
else if($questionType == 2){
$builder->add('answer', ChoiceType::class, array(
'label' => $question,
'multiple' => false, 'expanded' => false,
'choices' => array('SI' => 'SI', 'NO' => 'NO',),
));
}
else ...
}
我有一个实体 Report,它包含许多 Answers。
class Report
{
/**
* @ORM\OneToMany(targetEntity="App\Entity\Answer", mappedBy="report")
*/
private $answers;
...
}
class Answer
{
/**
* @ORM\ManyToOne(targetEntity="Report", inversedBy="answers")
*/
private $report;
...
}
我在 ReportType 中手动添加问题(我知道这不是最好的方法,但问题永远不会改变,我只对答案感兴趣。)
class ReportAnswersType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('answers', ChoiceType::class, array(
'label' => 'Room state',
'multiple' => false, 'expanded' => false,
'choices' => array('OK' => 'OK', 'NG' => 'NG', 'NP' => 'NP',),
))
->add('answers', IntegerType::class, array(
'label' => 'Temperature',
))
->add('answers', ChoiceType::class, array(
'label' => 'Is it good?',
'multiple' => false, 'expanded' => false,
'choices' => array('YES' => 'YES', 'NO' => 'NO',),
))
...
}
->add('save', SubmitType::class);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => Report::class,
));
}
我想做的是生成一个包含 3 个问题的表单,并将每个答案插入数据库。
但是呈现的表格只显示最后一个问题(因为每个 ->add('answers', ...) 我替换最后一个添加的)。
我尝试了不同的解决方案来解决这个问题:
- 遵循 How to Embed a Collection of Forms 上的文档,其中包括将每个答案(带有问题标签)添加到 Controller 中的 Report,然后呈现 ReportType。问题是我的每个问题都有不同的类型(选择、文本、整数...),我不知道如何单独定制它们。
- 我也尝试在我的 ReportType 中做 this,但它只显示最后添加的问题。
感谢任何帮助,谢谢!
可以使用Entity-Attribute-Value模型来解决这个问题。我建议使用 sidus/eav-model-bundle。这将是一项大量的工作,但您会学到很多东西。使用 EAV 模型,您可以有 N 个问题和答案。 我想不出使用简单的表单类型来解决这个问题。
我设法让它工作了。最后我按照 How to Embed a Collection of Forms.
上的说明进行操作
为了让它工作,我将字段 question 和 questionType 添加到我的 Answer 实体中。在 AnswerType.php 上,我每次都会检查它是什么类型的问题,然后根据它创建答案的类型。它看起来像这样:
$builder->addEventListener(FormEvents::POST_SET_DATA, function ($event) {
$builder = $event->getForm();
$answer = $event->getData();
$questionType = $answer->getQuestionType();
$question = $answer->getQuestion();
if ($questionType == 1){
$builder->add('answer', ChoiceType::class, array(
'label' => $question,
'multiple' => false, 'expanded' => false,
'choices' => array('OK' => 'OK', 'NG' => 'NG', 'NP' => 'NP',),
));
}
else if($questionType == 2){
$builder->add('answer', ChoiceType::class, array(
'label' => $question,
'multiple' => false, 'expanded' => false,
'choices' => array('SI' => 'SI', 'NO' => 'NO',),
));
}
else ...
}