我有一个关于Symfony表单事件的问题,我有2个对象:User和Address,一个User可以有一个mainAddress和一个subAddress,也可以为它们使用相同的地址(mainAddress)。
但是,当我编辑以前具有子地址的用户时,由于我们发送的表单中没有有关该子地址的数据,因此在POST_SUBMIT中将其设置为空。就我而言,我想用上一个对象填充它。
我有这个用户实体:
class User
{
...
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Address", cascade={"persist", "remove"})
* @ORM\JoinColumn(nullable=true)
* @Assert\Valid()
*/
private $mainAddress;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Address", cascade={"persist", "remove"})
* @ORM\JoinColumn(nullable=true)
* @Assert\Valid()
*/
private $subAddress;
}
还有一个地址实体:
class Address
{
/**
* @ORM\Column(type="string", length=255)
* @Assert\NotBlank()
*/
private $country;
/**
* @ORM\Column(type="string", length=255)
* @Assert\NotBlank()
*/
private $fullName;
...
}
地址表格类型:
class AddressType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('country', CountryType::class, [
'label' => 'label.country',
'preferred_choices' => ['FR'],
])
->add('fullName', TextType::class, [
'label' => 'label.full_name',
])
...
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Address::class,
]);
}
}
最后是我的使用事件监听器的UserType:
class UserType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('email', EmailType::class, [
'label' => 'label.email',
])
->add('mainAddress', AddressType::class)
->add('singleAddress', CheckboxType::class, [
'required' => false,
])
;
$formSubAddressModifier = function (FormInterface $form, bool $singleAddress) {
if (false === $singleAddress && false === $form->has('subAddress')) {
$form->add('subAddress', AddressType::class);
} elseif (true === $singleAddress && true === $form->has('subAddress')) {
$form->remove('subAddress');
}
};
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($formSubAddressModifier) {
$formSubAddressModifier($event->getForm(), $event->getData()->getSingleAddress());
});
$builder->get('singleAddress')->addEventListener(FormEvents::POST_SUBMIT, function(FormEvent $event) use ($formSubAddressModifier) {
$singleAddress = $event->getForm()->getData();
$formSubAddressModifier($event->getForm()->getParent(), $singleAddress);
});
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => User::class,
]);
}
}