我正在Symfony 3.4上构建一个小工具,我遇到了两个关于表单的问题,但是我无法找到解决方案。
为了背景说明,引起困难的表单基于Doctrine实体:Event。该事件引用另一个实体:一个Doctrine(与ORM无关)。Doctrine引用多个配件。 对于给定的具有给定Doctrine的事件,我想显示从Doctrine配件构建的集合类型,以公开此配件所需数量的数字。
这导致我的表单中有3个实体:事件本身,Doctrine和由我构建的FittingRequirements的CollectionType。 右侧面板内容旨在随着教义的更改而更改。
以下是 EventType:
我正在构建事件适配要求列表,并在 PRE_SET_DATA 和 POST_SUBMIT 中添加它。 如您所见,我使用 FittingRequirementType 的 CollectionType,如下所示:
为了背景说明,引起困难的表单基于Doctrine实体:Event。该事件引用另一个实体:一个Doctrine(与ORM无关)。Doctrine引用多个配件。 对于给定的具有给定Doctrine的事件,我想显示从Doctrine配件构建的集合类型,以公开此配件所需数量的数字。
这导致我的表单中有3个实体:事件本身,Doctrine和由我构建的FittingRequirements的CollectionType。 右侧面板内容旨在随着教义的更改而更改。
以下是 EventType:
<?php
namespace AppBundle\Form;
use AppBundle\Entity\Doctrine;
use AppBundle\Entity\Event;
use AppBundle\Form\DataTransformer\FittingRequirementTransformer;
use Doctrine\ORM\EntityRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class EventType extends AbstractType
{
protected $requirementTransformer;
public function __construct(FittingRequirementTransformer $transformer)
{
$this->requirementTransformer = $transformer;
}
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->setMethod('POST')
->add('name')
->add(
'date',
DateTimeType::class,
[
'widget' => 'single_text',
'format' => 'yyyy-MM-dd HH:mm',
]
)
->add('startLocation')
->add(
'eventType',
ChoiceType::class,
[
'choices' => [
'PvE' => 'PvE',
'PvP' => 'PvP',
'Other' => 'Other',
],
]
)
->add('target')
->add('description')
->add(
'doctrine',
EntityType::class,
[
'class' => 'AppBundle\Entity\Doctrine',
'choice_label' => 'name',
'query_builder' => function (EntityRepository $repository) {
return $repository->createQueryBuilder('d')->orderBy('d.name', 'ASC');
},
'required' => false,
]
);
$formModifier = function (FormInterface $form, Doctrine $doctrine = null, Event $event) {
$eventRequirements = [];
if ($doctrine) {
$doctrineFittings = $doctrine->getFittings();
$doctrineRequirements = $event->getDoctrineFittingRequirements($doctrine);
$eventRequirements = $this->requirementTransformer->dataToForm(
$doctrineFittings,
$doctrineRequirements,
$event
);
}
$form->add(
'eventRequirements',
CollectionType::class,
[
'entry_type' => FittingRequirementType::class,
'label' => false,
'entry_options' => ['label' => false],
'data' => $eventRequirements,
'mapped' => false,
]
);
};
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($formModifier) {
$formupEvent = $event->getData();
$formModifier($event->getForm(), $formupEvent->getDoctrine(), $formupEvent);
}
);
$builder->get('doctrine')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) use ($formModifier) {
$eventForm = $event->getForm()->getParent();
$doctrine = $event->getForm()->getData();
$formModifier($event->getForm()->getParent(), $doctrine, $eventForm->getData());
}
);
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(
[
'data_class' => 'AppBundle\Entity\Event',
]
);
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'event';
}
}
我正在构建事件适配要求列表,并在 PRE_SET_DATA 和 POST_SUBMIT 中添加它。 如您所见,我使用 FittingRequirementType 的 CollectionType,如下所示:
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\NumberType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class FittingRequirementType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('number', NumberType::class);
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\FittingRequirement'
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'appbundle_fittingrequirement';
}
}
这仅用于公开所需配件的数量。
当我显示表单时,所有这些都很好运作,但是当我使用JavaScript提交表单以刷新要求部分时,字段确实被替换,但返回的表单中输入框没有值。
来自我的 $formModifier 的 $eventRequirements 变量包含 适当的数据集,具有数字值。然而,当我使用 Symfony 分析器检查 XHR 时,表单没有值,即使我再次选择原始 Doctrine。我不明白发生了什么以及如何解决这个问题。
感谢您的阅读。