【发布时间】:2016-03-20 07:56:13
【问题描述】:
我有一个雇主档案表格,我正在尝试将Employer 所在的State 与City 链接起来,这部分工作正常,但 FormType 太长了,其他地方将需要此功能所以我决定将这个逻辑移到 EventSubscriber 中,并在我需要的地方重用它。
我遇到的问题是我正在努力思考如何在 EventSubscriber 类中注入 EntityManager。
我知道我可以在我的services.yml 中添加以下代码,这应该可以,但它不起作用。
app.form.location:
class: AppBundle\Form\EventListener\AddStateFieldSubscriber
arguments: ['@doctrine.orm.entity_manager']
tags:
- { name: kernel.event_subscriber }
这是我的EmployerProfileType,我打电话给我的addEventSubscriber,也就是AddStateFieldSubscriber()
class EmployerProfileType extends AbstractType
{
protected $em;
function __construct(EntityManager $em)
{
$this->em = $em;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('firstName', TextType::class)
->add('lastName', TextType::class)
->add('companyName', TextType::class)
->add('companyProfile', TextareaType::class)
->add('companyLogo', FileType::class, array(
'data_class' => null
));
$builder->addEventSubscriber(new AddStateFieldSubscriber());
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\EmployerProfile',
));
}
public function getName()
{
return 'app_bundle_emp_profile_type';
}
}
这是我的AddStateFieldSubscriber 类,我需要访问EntityManager
class AddStateFieldSubscriber implements EventSubscriberInterface
{
protected $em;
function __construct(EntityManager $em)
{
$this->em = $em;
}
public static function getSubscribedEvents()
{
// Tells the dispatcher that you want to listen on the form.pre_set_data
// event and that the preSetData method should be called.
return array(
FormEvents::PRE_SET_DATA => 'onPreSetData',
FormEvents::PRE_SUBMIT => 'onPreSubmit'
);
}
protected function addElements(FormInterface $form, States $province = null)
{
// Remove the submit button, we will place this at the end of the form later
// Add the province element
$form->add('state', EntityType::class, array(
'data' => $province,
'placeholder' => 'provide_state',
'class' => 'AdminBundle\Entity\States',
'mapped' => false)
);
// Cities are empty, unless we actually supplied a province
$cities = array();
if ($province) {
// Fetch the cities from specified province
$repo = $this->em->getRepository('AdminBundle:Cities');
$cities = $repo->findByStates($province, array('name' => 'asc'));
}
// Add the city element
$form->add('city', EntityType::class, array(
'placeholder' => 'provide_state_first',
'class' => 'AdminBundle\Entity\Cities',
'choices' => $cities,
));
}
function onPreSubmit(FormEvent $event) {
$form = $event->getForm();
$data = $event->getData();
// Note that the data is not yet hydrated into the entity.
$province = $this->em->getRepository('AdminBundle:States')->find($data['state']);
$this->addElements($form, $province);
}
function onPreSetData(FormEvent $event) {
$account = $event->getData();
$form = $event->getForm();
// We might have an empty account (when we insert a new account, for instance)
$province = $account->getCity() ? $account->getCity()->getStates() : null;
$this->addElements($form, $province);
}
}
我得到的错误是
可捕获的致命错误:参数 1 传递给 AppBundle\Form\EventListener\AddStateFieldSubscriber::__construct() 必须是 Doctrine\ORM\EntityManager 的一个实例,没有给出,调用 在 /Users/shairyar/Sites/clickjobboard/src/AppBundle/Form/EmployerProfileType.php 在第 48 行并定义
我正在通过服务注入EntityManager,那么为什么会出现此错误?
如果在EmployerProfileType里面我替换
$builder->addEventSubscriber(new AddStateFieldSubscriber();
到
$builder->addEventSubscriber(new AddStateFieldSubscriber($this->em));
然后一切都开始正常了。
我认为在 Symfony 中我们应该通过创建服务来注入依赖项?那么如何在我的AddStateFieldSubscriber() 类中注入EntityManager
我做错了什么?可能是我想多了。
将不胜感激任何反馈。
【问题讨论】:
-
这是绝对正常的行为。您正在自己创建订阅者的实例而不是请求它 - 因此您得到了例外。
app.form.location是您的服务的 ID,但您没有使用它。 -
@Artamiel 谢谢,是的,我明白了,所以如何
use:)
标签: php doctrine-orm dependency-injection symfony