Natrafiłeś na jeden z najtrudniejszych problemów z formularzami Symfony. Na szczęście istnieje dobra dokumentacja. Pozwól, że podsumuję ważne kroki.
Masz rację:jednostka Osoba musi wiedzieć o swojej relacji z PersonJob, jeśli chcesz manipulować tą relacją z punktu widzenia osoby. Musisz więc dodać właściwość:
// src/AppBundle/Entity/Person.php
/**
* @ORM\OneToMany(targetEntity="PersonJob", mappedBy="person")
*/
private $personJobs;
public function __construct()
{
$this->personJobs = new \Doctrine\Common\Collections\ArrayCollection();
}
a następnie będziesz miał w formularzu typ
// src/AppBundle/Form/PersonType.php
$builder
->add('name')
->add('firstname')
->add('personJobs', CollectionType::class, array(
'entry_type' => PersonJobType::class,
'allow_add' => true,
)
;
Zwróć uwagę na typ personJobs
pole. Ponieważ osoba może mieć wiele PersonJobs, potrzebujesz typu formularza, który może obsługiwać kolekcje. To jest cel wbudowanego CollectionType
(sprawdź jego dokumentację!
). Potrzebujesz również formularza typu PersonJobType
, aby CollectionType
umie budować podformularze:
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'
));
}
}
W celu debugowania zmień kontroler na
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(),
]);
}
Teraz skopiuj i wklej kod Twig i Javascript z Dodawanie i usuwanie elementów
(musisz dokonać drobnych zmian, takich jak zastąpienie form.emails
z form.personJobs
).
Formularz
Formularz będzie wyglądał jak
Tylko formularz Osoba z „Dodaj kolejne zadanie” link:
Dodawanie PersonJob:
Dodawanie czegoś PersonJob:
Otrzymane dane
Prześlij formularz i zobacz wynik 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]=> …
}
}
Pozostały jeszcze dwie rzeczy do zrobienia:
-
Ustaw
person
właściwość zagnieżdżonegoPersonJob
odpowiednio do nowej (ale jeszcze nie utrwalonej) osoby. -
Poinformuj Doctrine o nowym
PersonJob
podmioty, wywołując$em->persist(…)
na nich.