Php EventSubscriber内的Symfony access实体管理器
我有一个雇主简介表格,我正试图将Php EventSubscriber内的Symfony access实体管理器,php,doctrine-orm,dependency-injection,symfony,Php,Doctrine Orm,Dependency Injection,Symfony,我有一个雇主简介表格,我正试图将州雇主所在地与城市链接起来,这部分工作正常,但表格类型太长,网站的其他地方也需要此功能,所以我决定将此逻辑移到EventSubscriber中,并在其他地方重新使用它只要我需要它 我遇到的问题是,我正试图思考如何在EventSubscriber类中注入EntityManager 我知道我可以在我的服务中添加以下代码。yml应该可以,但它不起作用 app.form.location: class: AppBundle\Form\EventListener\A
州雇主所在地与城市链接起来,这部分工作正常,但表格类型太长,网站的其他地方也需要此功能,所以我决定将此逻辑移到EventSubscriber中,并在其他地方重新使用它只要我需要它
我遇到的问题是,我正试图思考如何在EventSubscriber
类中注入EntityManager
我知道我可以在我的服务中添加以下代码。yml
应该可以,但它不起作用
app.form.location:
class: AppBundle\Form\EventListener\AddStateFieldSubscriber
arguments: ['@doctrine.orm.entity_manager']
tags:
- { name: kernel.event_subscriber }
这是我的EmployeerProfileType
,我在这里调用我的AddEventsSubscriber
,它是AddStateFieldSubscriber()
这是我的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::\uu构造()
必须是条令\ORM\EntityManager的实例,未给定,已调用
在里面
/Users/shairyar/Sites/clickjobboard/src/AppBundle/Form/employeerprofiletype.php
在第48行,定义了
我正在通过服务注入EntityManager
,为什么会出现此错误
如果在employeerprofiletype
I内部,则更换
$builder->addEventSubscriber(新的AddStateFieldSubscriber();
到
$builder->addEventSubscriber(新的AddStateFieldSubscriber($this->em));
然后事情开始好转
我认为在Symfony中,我们应该通过创建服务来注入依赖项?那么我如何才能在我的AddStateFieldSubscriber()类中注入EntityManager
我做错了什么?可能是我想得太多了
非常感谢您的反馈。我想您需要将您的AddStateFieldSubscriber
标记为kernel.event\u订户
那么表单中的绑定就根本不需要了
相反,您需要检查正确的表单,如果表单不是使用该订阅服务器的表单,则跳出事件侦听器方法,因为事件将在任何表单上触发,而不仅仅是EmployerProfileType表单。我想您需要将AddStateFieldSubscriber
标记为kernel.event\u订阅服务器
那么表单中的绑定就根本不需要了
相反,您需要检查表单是否正确,如果表单不是使用该订阅服务器的表单,则跳出事件侦听器方法,因为事件将在任何表单上触发,而不仅仅是EmployerProfileType表单。这是绝对正常的行为。您是在自己创建订阅服务器的实例,而不是创建订阅服务器的实例请求它-因此你得到了一个例外。app.form.location
是你服务的ID,但你没有使用它。@Artamiel谢谢,是的,我理解,所以如何使用它:)这是绝对正常的行为。您自己创建了订阅者的一个实例,而不是请求它——因此出现了异常app.form.location
是您服务的ID,但您没有使用它。@Artamiel谢谢,是的,我理解,所以如何使用它:)谢谢,关于如何在活动订阅服务器中检查正确的表单,您可以分享一些代码吗?很抱歉,我自己从来没有这样做过$event->getForm->getName()?谢谢,关于如何在事件订阅服务器中检查正确的表单,您可以分享一些代码吗?很抱歉,我从来没有这样做过$事件->获取表单->获取名称()?
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);
}
}