Symfony 动态选择 2 个字段不起作用

问题描述 投票:0回答:0

我正在尝试链接 2 个选择,但出现错误“在空值上调用成员函数 getClasses()”

我试着按照这里的文档=>https://symfony.com/doc/current/form/dynamic_form_modification.html#dynamic-generation-for-submitted-forms

我的代码:

类实体

namespace App\Entity;

use App\Repository\ClassesRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: ClassesRepository::class)]
class Classes
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column(length: 50)]
    private ?string $name = null;

    #[ORM\ManyToOne(inversedBy: 'classes')]
    #[ORM\JoinColumn(nullable: false)]
    private ?Realm $realm = null;

    #[ORM\ManyToMany(targetEntity: Races::class, inversedBy: 'classes')]
    private Collection $race;

    public function __construct()
    {
        $this->race = new ArrayCollection();
        $this->items = new ArrayCollection();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }


    public function getRealm(): ?Realm
    {
        return $this->realm;
    }

    public function setRealm(?Realm $realm): self
    {
        $this->realm = $realm;

        return $this;
    }

    /**
     * @return Collection<int, Races>
     */
    public function getRace(): Collection
    {
        return $this->race;
    }

    public function addRace(Races $race): self
    {
        if (!$this->race->contains($race)) {
            $this->race->add($race);
        }

        return $this;
    }

//...

...//

    public function __toString()
    {
        return $this->getName();
    }
}

种族实体

namespace App\Entity;

use App\Repository\RacesRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: RacesRepository::class)]
class Races
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column(length: 15)]
    private ?string $name = null;

    #[ORM\ManyToOne(inversedBy: 'races')]
    #[ORM\JoinColumn(nullable: false)]
    private ?Realm $realm = null;

    #[ORM\ManyToMany(targetEntity: Classes::class, mappedBy: 'race')]
    private Collection $classes;


    public function __construct()
    {
        $this->classes = new ArrayCollection();
        $this->statsRaces = new ArrayCollection();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }



    /**
     * @return Collection<int, Classes>
     */
    public function getClasses(): Collection
    {
        return $this->classes;
    }

//...

...//


    public function __toString()
    {
        return $this->getName();
    }
}

The BDD

ClassesFormType

<?php

namespace App\Form;

use App\Entity\Races;
use App\Entity\Realm;
use App\Entity\Classes;
use App\Repository\RacesRepository;
use App\Repository\RealmRepository;
use App\Repository\ClassesRepository;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Positive;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Validator\Constraints\LessThanOrEqual;

class ClassesFormType extends AbstractType
{
    protected $realmRepository;
    protected $classesRepository;
    protected $racesRepository;

    public function __construct(RealmRepository $realmRepository, ClassesRepository $classesRepository, RacesRepository $racesRepository)
    {
        $this->realmRepository = $realmRepository;
        $this->classesRepository = $classesRepository;
        $this->racesRepository = $racesRepository;
    }

    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder->add('name', TextType::class, [
            'constraints' => new NotBlank(['message' => 'Veuillez entrer un nom'])
        ])
            ->add('level', IntegerType::class, [
                'constraints' => [
                    new Positive(['message' => 'Entrez un niveau entre 1 et 50']),
                    new LessThanOrEqual([
                        'value' => 50,
                        'message' => 'Le niveau doit être inférieur ou égal à 50'
                    ])
                ]
            ])
            ->add('classe', EntityType::class, [
                'constraints' => new NotBlank(['message' => 'Veuillez choisir une classe']),
                'class' => Classes::class,
                'attr' => [
                    'class' => 'classe'
                ],
                'choices' => [
                    "Albion" => $this->classesRepository->findBy(['realm' => 1], ['name' => 'ASC']),
                    "Hibernia" => $this->classesRepository->findBy(['realm' => 3], ['name' => 'ASC']),
                    "Midgard" => $this->classesRepository->findBy(['realm' => 2], ['name' => 'ASC']),
                ]
            ]);


        $formModifier = function (FormInterface $form, Classes $classe = null) {
            $races = null === $classe ? [] : $classe->getRace();

            $form->add('position', EntityType::class, [
                'class' => Races::class,
                'placeholder' => '',
                'choices' => $races,
            ]);
        };

        $builder->addEventListener(
            FormEvents::PRE_SET_DATA,
            function (FormEvent $event) use ($formModifier) {
                // this would be your entity, i.e. SportMeetup
                $data = $event->getData();

                $formModifier($event->getForm(), $data->getClasses()); // THIS IS THIS LINE!
            }
        );

        $builder->get('classe')->addEventListener(
            FormEvents::POST_SUBMIT,
            function (FormEvent $event) use ($formModifier) {
                // It's important here to fetch $event->getForm()->getData(), as
                // $event->getData() will get you the client data (that is, the ID)
                $classe = $event->getForm()->getData();

                // since we've added the listener to the child, we'll have to pass on
                // the parent to the callback function!
                $formModifier($event->getForm()->getParent(), $classe);
            }
        );
        // ->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
        //     $classe = $event->getData()['classe'] ?? null;


        //     $event->getForm()->add('race', EntityType::class, [
        //         'class' => Races::class,
        //         'attr' => [
        //             'class' => 'race'
        //         ],
        //         'constraints' => new NotBlank(['message' => 'Veuillez choisir une classe enrace']),
        //         'choice_label' => 'name',
        //         'disabled' => $classe === null,
        //         'choices' => $classe == null ? [] : $classe->getRace()
        //     ]);
        // });
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            //'data_class' => Classes::class,
        ]);
    }
}

你能帮帮我吗?

doctrine symfony-forms
© www.soinside.com 2019 - 2024. All rights reserved.