【问题标题】:Symfony inject parameter to form from buildFormSymfony 从 buildForm 注入参数到表单
【发布时间】:2018-08-29 08:56:20
【问题描述】:

我正在使用 Symfony

您会在我的 FeatureForm 下方找到:

            ->add('tags',CollectionType::class,
            array(
                'entry_type' =>TagFeatureType::class,
                'allow_add' => true,
                'allow_delete' => true,
                'data' => $datas,
                'entry_options' => array(
                    'label' => false,
                )
            )
        )

现在是我的 TagFeatureType:

            ->add('tag', EntityType::class,
            array(
                'choice_label' => 'name',
                'class' => 'AppBundle:Tag',
                'query_builder' => function(TagRepository $tr){
                    return $tr->findObjectNotMine();
                }
            )
        )

我想向 findOBjectNotMine 注入一个参数,但我无法从控制器传递参数,因为 TagFeatureType 是由 FeatureForm 创建的。在 buildForm 函数中,我不能传递任何额外的参数。

我看到了 2 个可能性,第一个我修改了默认选项以允许一个额外的选项,但这有点恶心。第二,我可以使用会话参数并在构造函数中注入会话服务......但它看起来更像是一种解决方法而不是正确的方法......

您知道从 FormType 中的 buildForm 函数向表单注入参数的优雅方法吗?

最好的问候

【问题讨论】:

    标签: php symfony symfony-forms


    【解决方案1】:

    如果您需要将容器已知参数传递给自定义表单类型,您可以按照上面尝试的方式进行(显然是通过参数注入)。但是,如果您想将数据从控制器向下传递到表单类型,您可以通过 $options(最后一个)参数(在 buildForm 中)传递它:

    特征表格

    public function buildForm(FormBuilderInterface $builder, array $options)
    
        // ....
    
        $builder->add('tags', CollectionType::class, array (
               'entry_type' => TagFeatureType::class,
               'allow_add' => true,
               'allow_delete' => true,
               'data' => $datas,
               'entry_options' => array(
                   'label' => false,
                   'some_custom_param' => $options['some_custom_param']
               )
           )
        );
    
        // ....
     }
    
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => Task::class
        ));
        $resolver->setRequired(array(
            'some_custom_param'
        ));
    }
    

    然后,TagFeatureType 中应该有配置选项:

    TagFeatureType

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setRequired(array(
            'some_custom_param'
        ));
    }
    

    最后,将其包含在 buildForm 中:

    public function buildForm(FormBuilderInterface $builder, array $options)
    
        // ....
        $someCustomParam = $options['some_custom_param'];
    
        // .... 
    
        $builder->add('tag', EntityType::class, array(
            'choice_label' => 'name',
            'class' => 'AppBundle:Tag',
            'query_builder' => function(TagRepository $tr) use ($someCustomParam) 
            {
                return $tr->findObjectNotMine($someCustomParam);
            }
        );
    
        // ....
    }
    

    这样做的明显缺点是路径中的所有表单都需要具有setRequiredsetDefault

    希望这会有所帮助...

    【讨论】:

    • 是的,它工作正常。我不知道我只能为一种表格更改额外的选项。我将您的帖子设置为答案,您能否编辑您的答案,因为您通过 $this 访问参数,它在 Symfony 2.8 中不起作用(也许稍后会起作用?)。我必须通过 $options 访问。之后你的答案将是完美的!你甚至更新了闭包;)
    【解决方案2】:

    在您的 TagFeatureType 中,您可以通过构造函数注入传入参数:

    class TagFeatureType extends AbstractType
    {
        private $tagRepository;
    
        public function __construct(TagRepository $tagRepository)
        {
            $this->tagRepository = $tagRepository;
        }
    
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $tr = $this->tagRepository;
            // ...
            ->add('tag', EntityType::class,
                array(
                    'choice_label' => 'name',
                    'class' => 'AppBundle:Tag',
                    'query_builder' => function(TagRepository $tr){
                        return $tr->findObjectNotMine();
                    }
                )
            )
        }
    }
    

    有一个DependencyInjectionExtension form extension会检查表单类型是否在服务容器中注册然后注入,而不是创建一个新实例。这应该确保标签存储库存在。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多