Symfony 从 buildForm 注入参数到表单
Symfony inject parameter to form from buildForm
我使用的是 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 函数向表单注入参数的优雅方法吗?
此致
如果您需要将容器已知的参数传递给自定义表单类型,您可以按照上面尝试的方式进行(显然是通过参数注入)。但是,如果你想将数据从控制器向下传递到表单类型,你可以通过 $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
.
希望这对您有所帮助...
在您的 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会检查表单类型是否在服务容器中注册然后注入,而不是创建一个新的实例。这应该确保标签存储库存在。
我使用的是 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 函数向表单注入参数的优雅方法吗?
此致
如果您需要将容器已知的参数传递给自定义表单类型,您可以按照上面尝试的方式进行(显然是通过参数注入)。但是,如果你想将数据从控制器向下传递到表单类型,你可以通过 $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
.
希望这对您有所帮助...
在您的 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会检查表单类型是否在服务容器中注册然后注入,而不是创建一个新的实例。这应该确保标签存储库存在。