Sie sind auf eines der schwierigsten Probleme mit Symfony-Formularen gestoßen. Glücklicherweise gibt es eine gute Dokumentation. Lassen Sie mich die wichtigsten Schritte zusammenfassen.
Sie haben Recht:Die Entität Person muss über ihre Beziehung zu PersonJob Bescheid wissen, wenn Sie diese Beziehung aus der Sicht einer Person manipulieren möchten. Sie müssen also eine Eigenschaft hinzufügen:
// src/AppBundle/Entity/Person.php
/**
* @ORM\OneToMany(targetEntity="PersonJob", mappedBy="person")
*/
private $personJobs;
public function __construct()
{
$this->personJobs = new \Doctrine\Common\Collections\ArrayCollection();
}
und dann haben Sie im Formulartyp
// src/AppBundle/Form/PersonType.php
$builder
->add('name')
->add('firstname')
->add('personJobs', CollectionType::class, array(
'entry_type' => PersonJobType::class,
'allow_add' => true,
)
;
Beachten Sie den Typ des personJobs
aufstellen. Da eine Person viele PersonJobs haben kann, benötigen Sie einen Formulartyp, der Sammlungen verarbeiten kann. Dies ist der Zweck des eingebauten CollectionType
(Sehen Sie sich seine Dokumentation an!
). Außerdem benötigen Sie den Formulartyp PersonJobType
, sodass CollectionType
weiß, wie man die Unterformulare baut:
class PersonJobType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('comment')
->add('datestart', DateTimeType::class)
->add('dateend', DateTimeType::class)
->add('job') // requires Job::__toString() to be defined!
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\PersonJob'
));
}
}
Ändern Sie zu Debugging-Zwecken Ihren Controller auf
public function testAction()
{
$person = new Person();
$form = $this->createForm(PersonType::class, $person);
$form->add('submit', SubmitType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
print '<pre>';
var_dump($form->getData());
die();
}
return $this->render('default/index.html.twig', [
'form' => $form->createView(),
]);
}
Machen Sie jetzt weiter und kopieren und fügen Sie den Twig- und Javascript-Code von Elemente hinzufügen und entfernen
(Sie müssen kleinere Änderungen vornehmen, z. B. das Ersetzen von form.emails
mit form.personJobs
).
Das Formular
Das Formular sieht folgendermaßen aus:
Nur das Personenformular mit einem „Weiteren Personenjob hinzufügen“ Link:
PersonJob hinzufügen:
Einen weiteren PersonJob hinzufügen:
Die empfangenen Daten
Senden Sie das Formular ab und sehen Sie sich die Ausgabe von var_dump
an :
object(AppBundle\Entity\Person)#247 (5) {
["id":"AppBundle\Entity\Person":private]=>
NULL
["name":"AppBundle\Entity\Person":private]=>
string(12) "Charles Dude"
["firstName":"AppBundle\Entity\Person":private]=>
string(7) "Charles"
["active":"AppBundle\Entity\Person":private]=>
bool(true)
["personJobs":"AppBundle\Entity\Person":private]=>
object(Doctrine\Common\Collections\ArrayCollection)#248 (1) {
["elements":"Doctrine\Common\Collections\ArrayCollection":private]=>
array(2) {
[0]=>
object(AppBundle\Entity\PersonJob)#962 (6) {
["id":"AppBundle\Entity\PersonJob":private]=>
NULL
["comment":"AppBundle\Entity\PersonJob":private]=>
string(19) "Something important"
["datestart":"AppBundle\Entity\PersonJob":private]=>
object(DateTime)#1088 (3) { … }
["dateend": …] => …
["person":"AppBundle\Entity\PersonJob":private]=>
NULL
["job":"AppBundle\Entity\PersonJob":private]=>
object(AppBundle\Entity\Job)#1171 (2) {
["id":"AppBundle\Entity\Job":private]=>
int(2)
["name":"AppBundle\Entity\Job":private]=>
string(5) "Job 2"
}
}
[1]=> …
}
}
Zwei Dinge müssen noch getan werden:
-
Legen Sie die
person
fest -Eigenschaft des verschachteltenPersonJob
Entitäten ordnungsgemäß an die neue (aber noch nicht beibehaltene) Person. -
Informieren Sie Doctrine über den neuen
PersonJob
Entitäten durch Aufruf von$em->persist(…)
auf ihnen.