在我的应用程序中,我有两个包(UserBundle和LocationBundle),它们之间有一个OneToOne关联。
LocationFormType链接了国家,州,城市字段表单独立工作正常但当我尝试将表单(LocationFormType)嵌入到UserRegistrationForm时,我无法访问国家/地区对象以检索相关的国家/地区。
Error: Call to a member function getCountry() on a non-object
我喜欢在两种模式下使用LocationFormType,嵌入到另一种形式或独立,可以任何正文帮助我修复我的代码
//LocationFormType
class LocationFormType extends AbstractType {
protected $em;
function __construct (EntityManager $em)
{
$this->em = $em;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('country', 'entity', array(
'empty_value' => '--Choose--',
'class' => 'AppLocationBundle:Country',
'query_builder' => function(EntityRepository $er)
{
return $er->createQueryBuilder('c')
->where('c.enabled = 1');
},
'label' => 'form.country',
'translation_domain' => 'AppLocationBundle'
));
$builder->addEventSubscriber(new LocationChainedFieldSubscriber($this->em));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'App\LocationBundle\Entity\Location'
));
}
public function getName()
{
return 'app_location_form';
}
}
位置表格事件订阅者
//EventSubscriber
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormInterface;
use Doctrine\ORM\EntityManager;
use App\LocationBundle\Entity\Country;
use Doctrine\ORM\EntityRepository;
class LocationChainedFieldSubscriber implements EventSubscriberInterface {
protected $em;
function __construct (EntityManager $em)
{
$this->em = $em;
}
public static function getSubscribedEvents()
{
return array(
FormEvents::PRE_SET_DATA => 'preSetData',
FormEvents::PRE_SUBMIT => 'preSubmit',
);
}
public function preSetData(FormEvent $event)
{
$form = $event->getForm();
$location = $event->getData();
// Problem occurs here when try to get data, the event data are null
//How to handle data passed from parent form to child form
//Might have an empty account(when we insert a new country)
$country = $location->getCountry() ? $location->getCountry() : null;
$this->addElement($form, $country);
}
public function preSubmit(FormEvent $event)
{
$form = $event->getForm();
$data = $event->getData();
//The data is not yet hydrated into the entity.
$country = $this->em->getRepository('AppLocationBundle:Country')->find($data->getCountry());
$this->addElement($form, $country);
}
protected function addElement(FormInterface $form, Country $country = null)
{
$states = array();
if($country)
{
//fetch the states form specific a country
$repo = $this->em->getRepository('AppLocationBundle:State');
$states = $repo->findByCountry($country, array('name' => 'asc'));
}
//Add the state element
$form->add('state', 'entity', array(
'choices' => $states,
'empty_value' => '--Choose--',
'class' => 'AppLocationBundle:State',
'mapped' => false
));
}
}
将表单位置用作服务
services:
app_location.form:
class: App\LocationBundle\Form\Type\LocationFormType
arguments: ['@doctrine.orm.entity_manager']
tags:
- { name: form.type, alias: app_location_form }
嵌入用户注册表单
//UserRegistrationForm
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
//other fields here
->add('name', 'text')
->add('location', 'app_location_form', array(
'data_class' => 'App\LocationBundle\Entity\Location',
'label' => 'form.location',
'translation_domain' => 'AppUserBundle'
));
public function getName()
{
return 'app_user_profile';
}
}
答案 0 :(得分:0)
// UserRegistrationForm
$builder->add('location', 'collection', array('location' => new LocationFormType ()));