如何从表单内部访问服务和配置
有时,你需要从你的表单类里去访问一个服务或其他配置信息。要实现这个,有两种可能:
1) 传递选项到你的表单 ¶
最简单的方式是,通过form options(表单选项)来传入服务或配置。假设你需要访问doctrine.orm.entity_manager
服务,以便能够进行查询。首先,允许(实际上是“必须”)一个新的entity_manager
选项传入到你的表单中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// src/AppBundle/Form/TaskType.PHP
// ...
class TaskType extends AbstractType
{
// ...
public function configureOptions(OptionsResolver $resolver)
{
// ...
$resolver->setRequired('entity_manager');
}
} |
做完这个,在创建表单时,你必须 传入一个entity_manager
选项:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// src/AppBundle/Controller/DefaultController.php
use AppBundle\Form\TaskType;
// ...
public function newAction()
{
$task = ...;
$form = $this->createForm(TaskType::class, $task, array(
'entity_manager' => $this->get('doctrine.orm.entity_manager')
));
// ...
} |
最后,entity_manager
选项可以在buildForm
方法中的$options
参数中被访问到:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// src/AppBundle/Form/TaskType.php
// ...
class TaskType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
/** @var \Doctrine\ORM\EntityManager $em */
$em = $options['entity_manager'];
// ...
}
// ...
} |
使用这种方式可以把任何东西 传入到你的表单。
2) 把表单定义成服务 ¶
另一种可能是,把你的表单类定义成服务。如果你希望在多处复用表单的话,这是个好办法——把它注册成服务可以令事情更简单。
假设你需要访问doctrine.orm.entity_manager
服务以便能够查询。首先,把它作为参数添加到你的表单类中:
1 2 3 4 5 6 7 8 9 |
// src/AppBundle/Resources/config/services.php
$container
->register(
'app.form.type.task',
'AppBundle\Form\TaskType'
)
->addArgument('@doctrine.orm.entity_manager')
->addTag('form.type')
; |
接下来,注册表单类为服务,并打上form.type
标签:
1 2 3 4 5 6 7 |
# src/AppBundle/Resources/config/services.yml
services:
app.form.type.task:
class: AppBundle\Form\TaskType
arguments: ['@doctrine.orm.entity_manager']
tags:
- { name: form.type } |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<!-- src/AppBundle/Resources/config/services.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="Http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="app.form.type.task" class="AppBundle\Form\TaskType">
<argument type="service" id="doctrine.orm.entity_manager"/>
<tag name="form.type" />
</service>
</services>
</container> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// src/AppBundle/Form/TaskType.php
use Doctrine\ORM\EntityManager;
// ...
class TaskType extends AbstractType
{
private $em;
public function __construct(EntityManager $em)
{
$this->em = $em;
}
// ...
} |
完成!在控制器中——也就是你创建表单的地方——什么也不需要动:Symfony足够智能地从服务容器中加载TaskType
。
参考把表单字段创建成一个服务以了解更多。