Symfony 从 buildForm 注入参数到表单



我正在使用Symfony <4,并且在多对多关系中使用带有参数的表单时遇到问题。

您将在下面找到我的功能表单:

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

现在我的标签特征类型:

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

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

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

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

此致敬意

如果您需要将容器已知的参数传递给自定义表单类型,您可以按照上面尝试的方式(显然是通过参数注入(。但是,如果要将数据从控制器向下传递到表单类型,可以通过$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应该配置选项:

标签特征类型

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

希望这有帮助...

在 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 表单扩展,它将检查表单类型是否已在服务容器中注册,然后注入它,而不是创建新实例。这应该确保标记存储库存在。

最新更新