【问题标题】:Embedding a dynamically generated form into another将动态生成的表单嵌入到另一个表单中
【发布时间】:2017-08-09 16:55:04
【问题描述】:

我使用 Symfony2.1 的 FormBuilder 在控制器中创建动态表单:

$form = $this->createFormBuilder($defaultData);
$form->add('field','text');

我想以同样的方式嵌入另一个表单,并将其嵌入到主表单中。

$subForm = $this->createFormBuilder();
$subForm->add('subfield','text');

// Does not work
$form->add('subform', $subForm);

很遗憾,此设置无法正常工作。我找不到任何方法如何将动态生成的子表单添加到动态生成的表单中,如上面的示例。

我缺少什么函数调用?

上面的示例代码抛出的异常是

UnexpectedTypeException:预期的参数类型为“字符串或 Symfony\Component\Form\FormTypeInterface", 给出“Symfony\Component\Form\Form”。

【问题讨论】:

    标签: php forms symfony symfony-forms symfony-2.1


    【解决方案1】:

    我会在两个单独的字段中创建两个表单类:

    <?php
    
    namespace Acme\DemoBundle\Form\Type;
    
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\OptionsResolver\OptionsResolverInterface;
    
    class FirstFormType extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                ->add('field', 'text')
                ->add('subform', new SecondFormType());
        }
    
        public function setDefaultOptions(OptionsResolverInterface $resolver)
        {
            $resolver->setDefaults(array(
                'data_class' => 'Acme\DemoBundle\Entity\FirstEntity'
            ));
        }
    
        public function getName()
        {
            return 'first';
        }
    }
    
    
    
    <?php
    
    namespace Acme\DemoBundle\Form\Type;
    
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\OptionsResolver\OptionsResolverInterface;
    
    class SecondFormType extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                ->add('subfield', 'text');
        }
    
        public function setDefaultOptions(OptionsResolverInterface $resolver)
        {
            $resolver->setDefaults(array(
                'data_class' => 'Acme\DemoBundle\Entity\SecondEntity',
            ));
        }
    
        public function getName()
        {
            return 'second';
        }
    }
    

    创建后,您可以使用此行从任何控制器创建表单以创建表单:

    $form = $this->createForm(new FirstFormType());
    

    或对于版本形式:

    $form = $this->createForm(new FirstFormType(), $first);
    

    在您的示例代码中,您试图将整个表单而不是表单类型分配给字段。

    希望对你有帮助

    【讨论】:

      【解决方案2】:

      推荐的 symfony 方式是创建单独的 FormType 类,如上所述。但如果你真的想..

      您可以通过调用将动态子表单添加到表单构建器中

      $formBuilder->add($subform /* FormBuilder */);
      

      如果使用 $this-&gt;createFormBuilder(); 创建此子表单,则名称为 "form",这意味着您不能添加以这种方式创建的两个或多个子表单 - 较新的子表单将覆盖以前的具有相同名称的子表单。

      如果您需要添加多个子表单,则必须使用创建它们的构建器

      $this->get('form.factory')->createNamedBuilder($uniqName)
      

      【讨论】:

      • 谢谢,这个解决方案非常适合我原来(和旧)问题的范围。关键确实是对FormFactory::createNamedBuilder()的调用。
      • 有时你不是很想,但真的需要:) 这是最好的答案,不知道为什么另一个人有这么多的赞成票。
      【解决方案3】:

      无需创建类...在控制器动作中:

      $subFormBuilder = $this->createFormBuilder(
              null /* default data */, 
              ['label' => 'Sub Form'] /* options */
          )
          ->add('name');
      
      $form = $this->createFormBuilder()
          ->add($subFormBuilder)
          ->add('number')
          ->getForm();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-01-29
        • 2021-09-06
        • 2019-03-11
        • 1970-01-01
        • 2012-04-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多