您遇到了 Symfony 表单最难的问题之一。幸运的是,有一些很好的文档。让我总结一下重要的步骤。
你是对的:如果您想从 Person 的角度操纵该关系,则实体 Person 需要了解其与 PersonJob 的关系。所以你需要添加一个属性:
// src/AppBundle/Entity/Person.php
/**
* @ORM\OneToMany(targetEntity="PersonJob", mappedBy="person")
*/
private $personJobs;
public function __construct()
{
$this->personJobs = new \Doctrine\Common\Collections\ArrayCollection();
}
然后你将在表单中输入
// src/AppBundle/Form/PersonType.php
$builder
->add('name')
->add('firstname')
->add('personJobs', CollectionType::class, array(
'entry_type' => PersonJobType::class,
'allow_add' => true,
)
;
请注意的类型personJobs
场地。由于一个人可以拥有多个 PersonJobs,因此您需要一个可以处理集合的表单类型。这就是内置的目的CollectionType
(查看它的文档! https://symfony.com/doc/current/reference/forms/types/collection.html)。您还需要表单类型PersonJobType
, 以便CollectionType
知道如何构建子表单:
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'
));
}
}
出于调试目的,请将控制器更改为
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(),
]);
}
现在继续复制并粘贴 Twig 和 Javascript 代码添加和删除项目 https://symfony.com/doc/current/reference/forms/types/collection.html#adding-and-removing-items(您必须进行一些小的更改,例如替换form.emails
with form.personJobs
).
The form
表格看起来像
只是带有 a 的 Person 表单“添加另一个 PersonJob” link:
添加 PersonJob:
添加另一个人的工作:
收到的数据
提交表单并查看输出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]=> …
}
}
仍有两件事需要完成:
Set the person
嵌套的属性PersonJob
实体正确地分配给新的(但尚未持久化的)Person。
告诉 Doctrine 有关新内容的信息PersonJob
通过调用实体$em->persist(…)
在他们。
相关文档:
- 集合类型字段 https://symfony.com/doc/current/reference/forms/types/collection.html
- 如何嵌入表单集合 https://symfony.com/doc/current/cookbook/form/form_collections.html