Du har stött på ett av de svåraste problemen med Symfony-formulär. Lyckligtvis finns det bra dokumentation. Låt mig sammanfatta de viktiga stegen.
Du har rätt:Entitetspersonen behöver veta om sin relation med PersonJob om du vill manipulera den relationen från en persons synvinkel. Så du måste lägga till en egenskap:
// src/AppBundle/Entity/Person.php
/**
* @ORM\OneToMany(targetEntity="PersonJob", mappedBy="person")
*/
private $personJobs;
public function __construct()
{
$this->personJobs = new \Doctrine\Common\Collections\ArrayCollection();
}
och sedan kommer du att ha i formulärtypen
// src/AppBundle/Form/PersonType.php
$builder
->add('name')
->add('firstname')
->add('personJobs', CollectionType::class, array(
'entry_type' => PersonJobType::class,
'allow_add' => true,
)
;
Notera typen av personJobs
fält. Eftersom en person kan ha många PersonJobs behöver du en formulärtyp som kan hantera insamlingar. Detta är syftet med den inbyggda CollectionType
(kolla in dokumentationen!
). Du behöver också formulärtypen PersonJobType
, så att CollectionType
vet hur man bygger underformulären:
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'
));
}
}
För felsökningsändamål, ändra din kontroller till
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(),
]);
}
Gå nu vidare och kopiera och klistra in Twig och Javascript-koden från Lägga till och ta bort objekt
(du måste göra mindre ändringar som att ersätta form.emails
med form.personJobs
).
Formuläret
Formuläret kommer att se ut
Bara personformuläret med "Lägg till ytterligare ett personjobb" länk:
Lägga till ett PersonJob:
Lägger till något PersonJob:
Datan som tas emot
Skicka formuläret och se utdata från var_dump
:
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]=> …
}
}
Två saker återstår att göra:
-
Ställ in
person
egenskapen för den kapsladePersonJob
enheter korrekt till den nya (men ännu inte bevarade) personen. -
Berätta för Doctrine om det nya
PersonJob
enheter genom att anropa$em->persist(…)
på dem.