Symfony:具有嵌入形式的动态形式
Symfony: dynamic form with embded form
我有一个由 StrainGmoType 继承的主窗体 (StrainType),而 StrainGmoType 嵌入了一个 StrainPlasmidType。
在主窗体 (StrainType) 中,我有一个用户选择团队的字段,然后一些字段取决于此选择(在主窗体、子窗体和嵌入窗体中)。对于在主窗体或子窗体中声明的所有字段,它都有效。但是我有 2 个 CollectionType,在这个 CollectionType 中我有 ManyToMany 与参数的关系。然后我做了一个特定的类型 (StrainPlasmidType),在主要类型和子类型中,我在 CollectionType 中调用它们(在示例中仅在子类型中)。但是,我不能得到这种类型的团队字段,那么我不能做 PRE_SET_DATA、PRE_SUBMIT 或 POST_SUBMIT...
我尝试使用 inherit_data,但它不适用于这种情况。如何获取 StrainPlasmidType 中 team 字段的数据?
部分代码:
应变形式:
class StrainType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('team', EntityType::class, [
'class' => 'AppBundle\Entity\Team',
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('team')
->leftJoin('team.members', 'members')
->leftJoin('team.projects', 'projects')
->leftJoin('projects.members', 'project_members')
->where('members = :user')
->orWhere('project_members = :user')
->setParameter('user', $this->tokenStorage->getToken()->getUser());
},
'data' => $this->tokenStorage->getToken()->getUser()->getFavoriteTeam(),
'choice_label' => 'name',
'placeholder' => '-- select a team --',
'mapped' => false,
])
GmoStrain 形式:
class StrainGmoType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('strainPlasmids', CollectionType::class, [
'entry_type' => StrainPlasmidType::class,
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
'required' => false,
])
//...
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => 'AppBundle\Entity\Strain',
]);
}
public function getParent()
{
return StrainType::class;
}
}
菌株质粒类型:
class StrainPlasmidType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('plasmid', EntityType::class, [
'class' => 'AppBundle\Entity\Plasmid',
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('p')
->leftJoin('p.team', 'team')
->leftJoin('team.members', 'members')
->where('members = :user')
->setParameter('user', $this->tokenStorage->getToken()->getUser())
->orderBy('p.autoName', 'ASC')
;
},
'group_by' => function (Plasmid $plasmid) {
return $plasmid->getTeam()->getName();
},
'choice_label' => function (Plasmid $plasmid) {
return $plasmid->getAutoName().' - '.$plasmid->getName();
},
'placeholder' => '-- select a plasmid --',
])
->add('state', ChoiceType::class, [
'choices' => [
'Replicative' => 'replicative',
'Integrated' => 'integrated',
'Cured' => 'cured',
],
'placeholder' => '-- select a state --',
])
;
最后,我只是使用表单的选项将数据发送到嵌入表单:
主要是:
$form->add('strainPlasmids', CollectionType::class, [
'entry_type' => StrainPlasmidType::class,
'entry_options' => [
'parent_data' => $team,
],
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
'required' => false,
]);
并且,在嵌入形式中:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('plasmid', EntityType::class, [
'class' => 'AppBundle\Entity\Plasmid',
'query_builder' => function (EntityRepository $er) use ($options) {
return $er->createQueryBuilder('p')
->leftJoin('p.team', 'team')
->where('team = :team')
->setParameter('team', $options['parent_data'])
->orderBy('p.autoName', 'ASC')
;
},
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => 'AppBundle\Entity\StrainPlasmid',
]);
$resolver->setRequired(array('parent_data'));
}
我有一个由 StrainGmoType 继承的主窗体 (StrainType),而 StrainGmoType 嵌入了一个 StrainPlasmidType。
在主窗体 (StrainType) 中,我有一个用户选择团队的字段,然后一些字段取决于此选择(在主窗体、子窗体和嵌入窗体中)。对于在主窗体或子窗体中声明的所有字段,它都有效。但是我有 2 个 CollectionType,在这个 CollectionType 中我有 ManyToMany 与参数的关系。然后我做了一个特定的类型 (StrainPlasmidType),在主要类型和子类型中,我在 CollectionType 中调用它们(在示例中仅在子类型中)。但是,我不能得到这种类型的团队字段,那么我不能做 PRE_SET_DATA、PRE_SUBMIT 或 POST_SUBMIT...
我尝试使用 inherit_data,但它不适用于这种情况。如何获取 StrainPlasmidType 中 team 字段的数据?
部分代码:
应变形式:
class StrainType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('team', EntityType::class, [
'class' => 'AppBundle\Entity\Team',
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('team')
->leftJoin('team.members', 'members')
->leftJoin('team.projects', 'projects')
->leftJoin('projects.members', 'project_members')
->where('members = :user')
->orWhere('project_members = :user')
->setParameter('user', $this->tokenStorage->getToken()->getUser());
},
'data' => $this->tokenStorage->getToken()->getUser()->getFavoriteTeam(),
'choice_label' => 'name',
'placeholder' => '-- select a team --',
'mapped' => false,
])
GmoStrain 形式:
class StrainGmoType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('strainPlasmids', CollectionType::class, [
'entry_type' => StrainPlasmidType::class,
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
'required' => false,
])
//...
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => 'AppBundle\Entity\Strain',
]);
}
public function getParent()
{
return StrainType::class;
}
}
菌株质粒类型:
class StrainPlasmidType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('plasmid', EntityType::class, [
'class' => 'AppBundle\Entity\Plasmid',
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('p')
->leftJoin('p.team', 'team')
->leftJoin('team.members', 'members')
->where('members = :user')
->setParameter('user', $this->tokenStorage->getToken()->getUser())
->orderBy('p.autoName', 'ASC')
;
},
'group_by' => function (Plasmid $plasmid) {
return $plasmid->getTeam()->getName();
},
'choice_label' => function (Plasmid $plasmid) {
return $plasmid->getAutoName().' - '.$plasmid->getName();
},
'placeholder' => '-- select a plasmid --',
])
->add('state', ChoiceType::class, [
'choices' => [
'Replicative' => 'replicative',
'Integrated' => 'integrated',
'Cured' => 'cured',
],
'placeholder' => '-- select a state --',
])
;
最后,我只是使用表单的选项将数据发送到嵌入表单:
主要是:
$form->add('strainPlasmids', CollectionType::class, [
'entry_type' => StrainPlasmidType::class,
'entry_options' => [
'parent_data' => $team,
],
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
'required' => false,
]);
并且,在嵌入形式中:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('plasmid', EntityType::class, [
'class' => 'AppBundle\Entity\Plasmid',
'query_builder' => function (EntityRepository $er) use ($options) {
return $er->createQueryBuilder('p')
->leftJoin('p.team', 'team')
->where('team = :team')
->setParameter('team', $options['parent_data'])
->orderBy('p.autoName', 'ASC')
;
},
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => 'AppBundle\Entity\StrainPlasmid',
]);
$resolver->setRequired(array('parent_data'));
}