如何从子表单中获取父Symfony3表单的值?

时间:2016-01-17 13:56:35

标签: forms symfony

我有一个包含嵌入表单的父表单。在嵌入式(子)表单中,我希望创建一个下拉字段,其中包含从数据库查询的另一个实体的选项。作为查询的一部分,我需要引用父实体,但不确定如何从子表单类访问该父对象。

例如,父级是$subscriber实体。在我的情况下,父表单实际上没有显示任何与订阅者相关的属性,只允许您添加或删除子实体表单。每个子表单必须具有上述字段,但选项必须限于订户已与之关系的值。

但这是我的问题所在。如何从子表单中使用的代码访问下面的$subscriber变量?:

$builder->add('otherEntity', EntityType::class, array(
    'class' => "AppBundle:YetAnotherEntity",
    'label' => "Other Entity",
    'query_builder' => $this->manager->getRepository("AppBundle:OtherEntity")->getOtherEntityBySubscriber($subscriber)
 ));

反过来在我的存储库中调用此函数:

public function getOtherEntityBySubscriber($subscriber)
{
    return $this->getEntityManager()
        ->createQuery(
            'SELECT o FROM AppBundle:OtherEntity o JOIN n.subscriberOtherEntity so WHERE o.subscriber = :subscriber'
        )
        ->setParameter("subscriber", $subscriber)
        ->getResult();
}

在jbafford的推荐之后: 我尝试了你的第一个选项但我的问题是我的父表单调用类型CollectionType :: class而不是我的自定义类型...因为我打算制作一个可以添加多个子项的表单。我无法将任何自定义选项传递给CollectionType。我是否需要扩展CollectionType以使我自己的Type能够获得额外的选项?

我的父表单如下所示:     $ builder-> add(' child',CollectionType :: class,array(                     "条目类型" => ChildType ::类,                     " allow_add" =>真正,                     " by_reference" =>假,                     " allow_delete" =>真正)); 如果我添加订阅者作为上面的选项我得到一个错误基本上说它不是一个有效的选项。我玩弄了我的ChildType扩展CollectionType,但我不认为我需要做什么,并得到一个错误说:
表单的视图数据应该是AppBundle \ Entity \ Child类的实例,但是是Doctrine \ ORM \ PersistentCollection类的实例。您可以通过设置" data_class"来避免此错误。 null的选项或添加视图转换器,将类Doctrine \ ORM \ PersistentCollection的实例转换为AppBundle \ Entity \ Child的实例。

我想我需要另一个类扩展CollectionType只是为了放入上面的add方法,但我仍然希望我的条目类型是ChildType :: class

1 个答案:

答案 0 :(得分:3)

由于$subscriber是您父表单的主题,因此您可以执行此操作的一种方法是将$subscriber作为表单选项传递给子表单。

你可以在孩子中定义它:

class ChildForm extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $subscriber = $options['subscriber'];
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setRequired(['subscriber']);
    }
}

然后从父母传递它。

如果您的父表单是根表单,则可以从$subscriber中获取$options['data']

        $builder->add('otherEntity', ChildForm::class, [
            'subscriber' => $options['data'],
        ],

如果没有,您可能需要使用事件监听器来获取表单数据:

    $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
        $subscriber = $event->getData();
        $form = $event->getForm();

        $form->add('otherEntity', ChildForm::class, [
            'subscriber' => $subscriber,
        ]);
    });