在 symfony 3.0 中将表单定义为服务
Define form as service in symfony 3.0
我知道还有 2 个其他问题,但我认为其中 none 解决了我要问的问题。
在 Symfony 2.8 中有一个关于用 "alias" 标记定义为服务的表单的弃用说明,thant 可用于传递给 "createForm" 以获取表单。
所以如果我错了请纠正我,现在我们必须定义没有别名标签的服务:
#src/MyBundle/Resources/config/services.yml
my.form.as.service:
class: MyBundle\Form\Type\MyFormType
arguments: ["@doctrine.orm.entity_manager",%myparameter1%]
tags: { - name: form.type }
在控制器中:
$form = $this->createForm('my.form.as.service');
但这给了我一个表单命名错误,如 getName 函数中的表单 returns 'my_name',它期望表单接收 FQCN。好的,按照控制器中的其他响应,我更改为:
use MyBundle\Form\Type\MyFormType;
...
$form = $this->createForm(MyFormType::class)
有效,在 github 中,symfony 成员说表单组件完成了所有工作...但是如果我想定义一个具有相同 class 但具有另一个参数的第二个服务怎么办而不是 %parameter1%。在 2.8 及更早版本中,我能够定义另一个服务并将其名称传递给 createForm 函数,但现在它直接获取 class,我可以这样做吗? (我知道这样做可能很奇怪或不必要或...)。
对于 symfony 成员:我同意 Javiereguiluz 的意见,这个改变会让你写更多的代码,并且让你无法完全控制表单组件如何使用你的服务。是否有必要删除表单别名以使我们的生活变得如此复杂?谢谢!
我问了同样的问题并在这里回答了自己:
不幸的是,这是 Symfony 3.0 的一个限制,没有解决方案。
一个解决方案是为每个表单创建一个 class(而不是一个通用表单),并使每个表单都扩展一个通用抽象 class 以避免代码重复。
但这仍然需要您创建许多 classes,这不是最优的。
抱歉,我一开始看错了你的问题。现在,正确答案:
如果您的表单类型需要动态配置设置(例如参数),则应改为创建表单类型选项。这允许动态更改此设置:
class MyFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $form, array $options)
{
$options['your_setting']; // read the option
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setRequired('your_setting'); // add a required option
}
}
用法:
$this->createForm(MyFormType::class, null, [
'your_setting' => 'some value',
]);
或者,您也可以将设置默认为某个静态值或参数:
class MyFormType extends AbstractType
{
private $yourSetting;
public function __construct($yourSetting)
{
$this->yourSetting = $yourSetting;
}
// ...
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefault('your_setting', $this->yourSetting);
}
}
您可以在 OptionsResolver component documentation 中阅读更多相关信息。
我知道还有 2 个其他问题,但我认为其中 none 解决了我要问的问题。
在 Symfony 2.8 中有一个关于用 "alias" 标记定义为服务的表单的弃用说明,thant 可用于传递给 "createForm" 以获取表单。
所以如果我错了请纠正我,现在我们必须定义没有别名标签的服务:
#src/MyBundle/Resources/config/services.yml
my.form.as.service:
class: MyBundle\Form\Type\MyFormType
arguments: ["@doctrine.orm.entity_manager",%myparameter1%]
tags: { - name: form.type }
在控制器中:
$form = $this->createForm('my.form.as.service');
但这给了我一个表单命名错误,如 getName 函数中的表单 returns 'my_name',它期望表单接收 FQCN。好的,按照控制器中的其他响应,我更改为:
use MyBundle\Form\Type\MyFormType;
...
$form = $this->createForm(MyFormType::class)
有效,在 github 中,symfony 成员说表单组件完成了所有工作...但是如果我想定义一个具有相同 class 但具有另一个参数的第二个服务怎么办而不是 %parameter1%。在 2.8 及更早版本中,我能够定义另一个服务并将其名称传递给 createForm 函数,但现在它直接获取 class,我可以这样做吗? (我知道这样做可能很奇怪或不必要或...)。
对于 symfony 成员:我同意 Javiereguiluz 的意见,这个改变会让你写更多的代码,并且让你无法完全控制表单组件如何使用你的服务。是否有必要删除表单别名以使我们的生活变得如此复杂?谢谢!
我问了同样的问题并在这里回答了自己:
不幸的是,这是 Symfony 3.0 的一个限制,没有解决方案。
一个解决方案是为每个表单创建一个 class(而不是一个通用表单),并使每个表单都扩展一个通用抽象 class 以避免代码重复。
但这仍然需要您创建许多 classes,这不是最优的。
抱歉,我一开始看错了你的问题。现在,正确答案:
如果您的表单类型需要动态配置设置(例如参数),则应改为创建表单类型选项。这允许动态更改此设置:
class MyFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $form, array $options)
{
$options['your_setting']; // read the option
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setRequired('your_setting'); // add a required option
}
}
用法:
$this->createForm(MyFormType::class, null, [
'your_setting' => 'some value',
]);
或者,您也可以将设置默认为某个静态值或参数:
class MyFormType extends AbstractType
{
private $yourSetting;
public function __construct($yourSetting)
{
$this->yourSetting = $yourSetting;
}
// ...
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefault('your_setting', $this->yourSetting);
}
}
您可以在 OptionsResolver component documentation 中阅读更多相关信息。