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

sno*_*168 3 symfony-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)
 ));
Run Code Online (Sandbox Code Playgroud)

它又在我的存储库中调用此函数:

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();
}
Run Code Online (Sandbox Code Playgroud)

在 jbafford 的建议之后:我尝试了您的第一个选项,但我的问题是我的父表单调用的类型CollectionType::class不是我的自定义类型...因为我计划制作一个可以添加多个子项目的表单。我无法将任何自定义选项传递给CollectionType. 我是否需要扩展CollectionType以创建能够接受额外选项的自己的类型?

我的父表单如下所示:

$builder->add('child', CollectionType::class, array(
  "entry_type" => ChildType::class,
  "allow_add" => true,
  "by_reference" => false,
  "allow_delete" => true)
);
Run Code Online (Sandbox Code Playgroud)

如果我将订阅者添加为上面的选项,我会收到一个错误,基本上说它不是有效的选项。我尝试让我的 ChildType 扩展 CollectionType 但我不认为这是我需要做的,并收到一条错误消息:

表单的视图数据应该是类 AppBundle\Entity\Child 的实例,但实际上是类 Doctrine\ORM\PersistentCollection 的实例。您可以通过将“data_class”选项设置为 null 或添加一个视图转换器将 Doctrine\ORM\PersistentCollection 类的实例转换为 AppBundle\Entity\Child 的实例来避免此错误。

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

jba*_*ord 5

您可以执行此操作的一种方法$subscriber是通过$subscriber给子表单,因为这是父表单的主题。

您可以在子项中这样定义它:

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

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setRequired(['subscriber']);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后从父母那里传递它。

如果您的父表单是根表单,您可以获取以下$subscriber内容$options['data']

        $builder->add('otherEntity', ChildForm::class, [
            'subscriber' => $options['data'],
        ],
Run Code Online (Sandbox Code Playgroud)

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

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

        $form->add('otherEntity', ChildForm::class, [
            'subscriber' => $subscriber,
        ]);
    });
Run Code Online (Sandbox Code Playgroud)

  • 不可以。您可以传递给 `CollectionType` 的选项之一是 `['options' => [传递给子元素的选项数组]]`。(Symfony >= 2.8 中的“entry_options”)http://symfony.com/doc/current/reference/forms/types/collection.html#entry-options (4认同)