Symfony动态表单(POST_SUBMIT),在嵌套对象属性中设置null

时间:2019-01-15 14:06:28

标签: symfony symfony-forms symfony4

我有一个关于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,
        ]);
    }
}

0 个答案:

没有答案