我正在使用Symfony <4,并且我在使用带有参数的多对多关系的其他表单的表单时遇到问题。
您将在我的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函数中向表单注入参数的一种优雅方法吗?
最诚挚的问候
答案 0 :(得分:1)
如果需要将容器已知的参数传递给自定义表单类型,则可以按照上面的尝试进行操作(显然是通过参数注入)。但是,如果要将数据从控制器向下传递到表单类型,则可以通过$options
(最后一个)参数(在buildForm
中)传递数据:
FeatureForm
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);
}
);
// ....
}
显而易见的缺点是,路径中的所有表单都必须具有setRequired
或setDefault
。
希望这对您有帮助...
答案 1 :(得分:0)
在您的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,它将检查表单类型是否已在服务容器中注册,然后注入它,而不是创建新实例。这应该确保标记存储库存在。