我正在尝试链接 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();
}
}
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,
]);
}
}
你能帮帮我吗?