【问题标题】:How to pass parameter to FormType constructor from controller如何将参数从控制器传递给 FormType 构造函数
【发布时间】:2016-08-22 16:13:27
【问题描述】:

在 Symfony2.7 中,我能够在创建表单时直接从控制器将参数传递给 Form Type 构造函数,但是在 Symfony3 中我无法做到!

在 Symfony2.7 之前

$postedBy = $this->getUser()->getFullname();
$form = $this->createForm(new NewsType($postedBy));

在 Symfony3 之后

$form = $this->createForm(NewsType::class); // no idea how to pass parameter?

更新: 我还想通过以下方式访问它:

$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
    // how to access posted_by_name here which is sent from controller
}

任何帮助将不胜感激..

【问题讨论】:

  • 感谢您的帮助,我自己解决了,请检查我的答案..
  • @jonathan - 对该问题的回答并不能完全回答我的问题!正如我的回答中更新的那样,我还需要在表单事件侦听器中传递参数..

标签: symfony-forms symfony


【解决方案1】:

感谢您的宝贵时间!我自己解决了这个问题:

我从 NewsType 构造函数中删除了参数,并使用 $options 数组将数据添加到 postedBy 表单字段,并将数据从控制器传递到 $options 数组,请检查以下内容:

NewsType

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('postedBy', HiddenType::class, array(
            'data' => $options['postedBy']
          )
        )
    ;
}

// WARNING: this is a MANDATORY block! Only options described here will be allowed to be passed.
public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'postedBy' => null,
    ));
}

控制器

$form = $this->createForm(NewsType::class, $news, array(
    'postedBy' => $this->getUser()->getFullname(),
);

更新: 如果您想从 addEventListener 访问 $options 数组,请使用以下代码:

$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
    $postedBy = $event->getForm()->getConfig()->getOptions()['postedBy'];
}

希望它可以帮助别人!

【讨论】:

    【解决方案2】:

    你需要定义你的form as service

    namespace AppBundle\Form\Type;
    
    use App\Utility\MyCustomService;
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\Form\Extension\Core\Type\SubmitType;
    
    class NewsType extends AbstractType
    {
        private $myCustomService;
    
        private $myStringParameter;
    
        public function __construct(MyCustomService $service, $stringParameter)
        {
            $this->myCustomService   = $service;
            $this->myStringParameter = $stringParameter;
        }
    
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            // Your code
        }
    }
    

    添加到您的服务配置中:

    #src/AppBundle/Resources/config/services.yml
    services:
        app.form.type.task:
            class: AppBundle\Form\Type\NewsType
            arguments:
                - "@app.my_service"
                - "posted_by_name"
            tags:
                - { name: form.type }
    

    【讨论】:

    • 这是个好主意,但是我需要一个可以通过 Controller + Form Type 完成的解决方案..
    • 对我来说,这感觉像是一种解决方法。使用“OptionsResolver”传递选项看起来是一个很好的做法。还是我错了?
    • 它很好地解决了上述问题..这就是我想要的:)
    • jkucharovic 有正确的答案。 symfony.com/doc/current/cookbook/form/… 也表示
    • 是的,这也是正确的解决方案,但我不需要在我的情况下创建单独的服务..
    【解决方案3】:

    你们都是对的。

    @Muzafar 和@jkucharovic,问题是何时使用哪个...

    正如 Bernard Schussek 在Symfony Forms 101 中展示的那样:

    1 不要将动态数据传递给构造函数..

    2 ...但改用自定义选项

    3全局设置传递给构造函数(或服务)

    【讨论】:

      猜你喜欢
      • 2017-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多