在我的Symfony2项目中,我需要在db中生成现有表的列表。由于并非所有表都用作项目中的实体,并且列表本身需要是一个简单的数组而不是实体,因此我为此编写了一个sql语句。此sql语句嵌入在自定义服务中的函数中(并已经过全面测试)。
现在,在表单类型中,我想用上面提到的函数的结果数组填充一个字段。这些成为用户可以选择的选项。
我的问题是如何在表单类型中访问服务?
答案 0 :(得分:15)
有一个简单的解决方案,它是纯OOP,没有特定于框架的配置。 只需使用构造函数手动将服务实例注入表单类型实例:
class SomeType extends AbstractType
{
private $provider;
public function __construct(DataBaseTableNameProvider $provider)
{
$this->provider = $provider;
}
public function buildForm(FormBuilder $builder, array $options)
{
$builder->add('tables', 'choices', array(
'choices' => $this->provider->getTableNames(),
));
}
}
然后,在你的控制器中例如:
public function newAction()
{
$form = $this->createForm(new SomeType($this->get('table_name_provider'));
// more stuff
}
使用框架配置完全相同,遵循http://symfony.com/doc/2.0/cookbook/form/create_custom_field_type.html#creating-your-field-type-as-a-service。
唯一的区别是它需要注意使用DIC实例化你的类型,并注入正确的依赖项。然后,您只需要修改控制器:
public function newAction()
{
$form = $this->createForm('some_type_alias');
// more stuff
}
答案 1 :(得分:7)
表单类型中的翻译服务访问示例:
您的表单类型:
class TaskType extends AbstractType {
....
public function setDefaultOptions(OptionsResolverInterface $resolver) {
$resolver->setDefaults(array(
't' => 'Symfony\Bundle\FrameworkBundle\Translation\Translator',
));
}
public function buildForm(FormBuilderInterface $builder, array $options) {
$t = $options['t'];
$t->trans('string to translate');
....
}
控制器:
public function someAction() {
$form = $this->createForm(new TaskType(),
$task,
array('t' => $this->get('translator')));
答案 2 :(得分:2)
您还可以将表单类型注册为服务。这只是需要的 如果你的表单类型需要一些依赖项来注入 容器,否则是不必要的开销,因此不是 建议对所有表单类型类执行此操作。
# src/AppBundle/Resources/config/services.yml
services:
app.form.type.gender:
class: AppBundle\Form\Type\ SomeType
arguments:
- "@app.table_name_provider"
tags:
- { name: form.type }
$form = $this->createForm(SomeType::class)
答案 3 :(得分:1)
Symfony 3.X的更新,你现在有两个选择......
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setRequired('option_key');
}
然后将其传递给控制器
$form = $this->createForm(XXXType::class, $entity, array(
'option_key' => $this->get('service_you_want_to_call')
));
此选项更清晰IMO,您无需在调用表单的任何地方发送选项
class XXXType extends AbstractType
{
private $service;
public function __construct(ServiceType $service)
{
$this->service = $service;
}
然后在配置中定义服务
services:
app.form.type.XXX:
class: AppBundle\Form\XXXType
arguments: ['@service_you_want_to_call']
tags:
- { name: form.type }
每次使用
调用表单时 $this->createForm(XXXType::class, $data, $options)
Symfony足够聪明,知道它必须使用该服务参数(因为form.type标签而知道它),所以你不再需要将任何数据传递给构造函数。
Symfony docs: How to Access Services or Config from Inside a Form