$event->getData() returns 嵌入式表单为空
$event->getData() returns null for an embedded form
我正在使用 symfony 2.3。我有一个带有事件侦听器的表单 "AddressType",它在单独实例化时按预期工作。但是当我将 AddressType 嵌入到 BusinessType 中时,地址表单没有显示。我不明白到底发生了什么,我该如何解决。
业务类型
class BusinessType extends AbstractType {
private $em;
public function __construct($em) {
$this->em = $em;
}
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options) {
// cela suppose que le gestionnaire d'entité a été passé en option
$entityManager = $options['em'];
$transformer = new EmailToUserTransformer($entityManager);
$ActivityTransformer = new ActivityToStringTransformer($entityManager);
$builder
->add('name')
->add('description')
->add('file')
->add('file2')
->add('email')
->add('fb')
->add('twitter')
->add('googlePlus')
->add('linkedin')
->add('tel')
->add('mobile')
->add('fax')
->add('web')
->add('address', new AddressType($this->em))
->add(
$builder->create('user', 'text')
->addModelTransformer($transformer)
)
->add('activity', null, array(
'empty_value' => 'Sélectionner une activité',
))
->add(
$builder->create('secondary', 'entity', array(
'empty_value' => 'Sélectionner une activité secondaire',
'class' => 'BiginfoAdminBundle:Activity',
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('a');
},
))
->addModelTransformer($ActivityTransformer)
)
->add('enabled')
->add('medias', 'collection', array(
'type' => new $options['media_form'],
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false))
->add('opens', 'collection', array(
'type' => new $options['open_form'],
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false))
;
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver) {
$resolver->setDefaults(array(
'data_class' => 'Biginfo\AdminBundle\Entity\Business',
));
$resolver->setDefaults(array(
'data_class' => 'Biginfo\AdminBundle\Entity\Business',
'open_form' => 'Biginfo\AdminBundle\Form\OpenType',
'media_form' => 'Biginfo\AdminBundle\Form\MediaType',
'cascade_validation' => true
));
$resolver->setRequired(array(
'em',
));
$resolver->setAllowedTypes(array(
'em' => 'Doctrine\Common\Persistence\ObjectManager',
));
}
/**
* @return string
*/
public function getName() {
return 'biginfo_adminbundle_business';
}
}
地址类型
class AddressType extends AbstractType {
private $em;
public function __construct($em) {
$this->em = $em;
}
public function buildForm(FormBuilderInterface $builder, array $options) {
$propertyPathToPostalCode = 'postalCode';
$builder
->add('street', 'text', array(
'label' => 'Adresse'
))
;
$builder
->addEventSubscriber(new AddGouvernauratFieldSubscriber($propertyPathToPostalCode, $this->em))
->addEventSubscriber(new AddDelegationFieldSubscriber($propertyPathToPostalCode, $this->em))
->addEventSubscriber(new AddSectorFieldSubscriber($propertyPathToPostalCode, $this->em))
->addEventSubscriber(new AddPostalCodeFieldSubscriber($propertyPathToPostalCode, $this->em))
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver) {
$resolver->setDefaults(array(
'data_class' => 'Biginfo\AdminBundle\Entity\Address',
));
}
public function getName() {
return 'address';
}
}
AddDelegationFieldSubscriber
class AddDelegationFieldSubscriber implements EventSubscriberInterface {
private $propertyPathToCity;
private $em;
public function __construct($propertyPathToCity, $em) {
$this->propertyPathToCity = $propertyPathToCity;
$this->em = $em;
}
public static function getSubscribedEvents() {
return array(
FormEvents::PRE_SET_DATA => 'preSetData',
FormEvents::PRE_SUBMIT => 'preSubmit'
);
}
private function addDelegationForm($form, $gouvernaurat_id, $delegation = null) {
$formOptions = array(
'class' => 'BiginfoAdminBundle:Delegation',
'empty_value' => 'Sélectionner une délégation',
'label' => 'Délégation',
'mapped' => false,
'attr' => array(
'class' => 'delegation_selector',
),
'query_builder' => function (EntityRepository $repository) use ($gouvernaurat_id) {
$qb = $repository->createQueryBuilder('delegation')
->innerJoin('delegation.gouvernaurat', 'gouvernaurat')
->where('gouvernaurat.id = :gouvernaurat')
->setParameter('gouvernaurat', $gouvernaurat_id)
;
return $qb;
}
);
if ($delegation) {
$formOptions['data'] = $delegation;
}
$form->add('delegation', 'entity', $formOptions);
}
public function preSetData(FormEvent $event) {
$data = $event->getData();
$form = $event->getForm();
if (null === $data) {
return;
}
/**
* Le composant PropertyAccess fournit des fonctions pour lire
* et écrire depuis/dans un objet ou un tableau en une simple chaîne de caractères.
*/
$accessor = PropertyAccess::getPropertyAccessor();
$sector1 = $accessor->getValue($data, 'sector');
$sector = $this->em->getRepository('BiginfoAdminBundle:Sector')
->findOneBy(array('name' => $sector1));
$delegation = ($sector) ? $sector->getDelegation() : null;
$gouvernaurat_id = ($delegation) ? $delegation->getGouvernaurat()->getId() : null;
$this->addDelegationForm($form, $gouvernaurat_id, $delegation);
}
public function preSubmit(FormEvent $event) {
$data = $event->getData();
$form = $event->getForm();
$gouvernaurat_id = array_key_exists('gouvernaurat', $data) ? $data['gouvernaurat'] : null;
$this->addDelegationForm($form, $gouvernaurat_id);
}
}
我遇到了同样的问题,但提到这个问题 #5694 你必须在父表单中设置 'prototype' => false。
我正在使用 symfony 2.3。我有一个带有事件侦听器的表单 "AddressType",它在单独实例化时按预期工作。但是当我将 AddressType 嵌入到 BusinessType 中时,地址表单没有显示。我不明白到底发生了什么,我该如何解决。
业务类型
class BusinessType extends AbstractType {
private $em;
public function __construct($em) {
$this->em = $em;
}
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options) {
// cela suppose que le gestionnaire d'entité a été passé en option
$entityManager = $options['em'];
$transformer = new EmailToUserTransformer($entityManager);
$ActivityTransformer = new ActivityToStringTransformer($entityManager);
$builder
->add('name')
->add('description')
->add('file')
->add('file2')
->add('email')
->add('fb')
->add('twitter')
->add('googlePlus')
->add('linkedin')
->add('tel')
->add('mobile')
->add('fax')
->add('web')
->add('address', new AddressType($this->em))
->add(
$builder->create('user', 'text')
->addModelTransformer($transformer)
)
->add('activity', null, array(
'empty_value' => 'Sélectionner une activité',
))
->add(
$builder->create('secondary', 'entity', array(
'empty_value' => 'Sélectionner une activité secondaire',
'class' => 'BiginfoAdminBundle:Activity',
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('a');
},
))
->addModelTransformer($ActivityTransformer)
)
->add('enabled')
->add('medias', 'collection', array(
'type' => new $options['media_form'],
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false))
->add('opens', 'collection', array(
'type' => new $options['open_form'],
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false))
;
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver) {
$resolver->setDefaults(array(
'data_class' => 'Biginfo\AdminBundle\Entity\Business',
));
$resolver->setDefaults(array(
'data_class' => 'Biginfo\AdminBundle\Entity\Business',
'open_form' => 'Biginfo\AdminBundle\Form\OpenType',
'media_form' => 'Biginfo\AdminBundle\Form\MediaType',
'cascade_validation' => true
));
$resolver->setRequired(array(
'em',
));
$resolver->setAllowedTypes(array(
'em' => 'Doctrine\Common\Persistence\ObjectManager',
));
}
/**
* @return string
*/
public function getName() {
return 'biginfo_adminbundle_business';
}
}
地址类型
class AddressType extends AbstractType {
private $em;
public function __construct($em) {
$this->em = $em;
}
public function buildForm(FormBuilderInterface $builder, array $options) {
$propertyPathToPostalCode = 'postalCode';
$builder
->add('street', 'text', array(
'label' => 'Adresse'
))
;
$builder
->addEventSubscriber(new AddGouvernauratFieldSubscriber($propertyPathToPostalCode, $this->em))
->addEventSubscriber(new AddDelegationFieldSubscriber($propertyPathToPostalCode, $this->em))
->addEventSubscriber(new AddSectorFieldSubscriber($propertyPathToPostalCode, $this->em))
->addEventSubscriber(new AddPostalCodeFieldSubscriber($propertyPathToPostalCode, $this->em))
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver) {
$resolver->setDefaults(array(
'data_class' => 'Biginfo\AdminBundle\Entity\Address',
));
}
public function getName() {
return 'address';
}
}
AddDelegationFieldSubscriber
class AddDelegationFieldSubscriber implements EventSubscriberInterface {
private $propertyPathToCity;
private $em;
public function __construct($propertyPathToCity, $em) {
$this->propertyPathToCity = $propertyPathToCity;
$this->em = $em;
}
public static function getSubscribedEvents() {
return array(
FormEvents::PRE_SET_DATA => 'preSetData',
FormEvents::PRE_SUBMIT => 'preSubmit'
);
}
private function addDelegationForm($form, $gouvernaurat_id, $delegation = null) {
$formOptions = array(
'class' => 'BiginfoAdminBundle:Delegation',
'empty_value' => 'Sélectionner une délégation',
'label' => 'Délégation',
'mapped' => false,
'attr' => array(
'class' => 'delegation_selector',
),
'query_builder' => function (EntityRepository $repository) use ($gouvernaurat_id) {
$qb = $repository->createQueryBuilder('delegation')
->innerJoin('delegation.gouvernaurat', 'gouvernaurat')
->where('gouvernaurat.id = :gouvernaurat')
->setParameter('gouvernaurat', $gouvernaurat_id)
;
return $qb;
}
);
if ($delegation) {
$formOptions['data'] = $delegation;
}
$form->add('delegation', 'entity', $formOptions);
}
public function preSetData(FormEvent $event) {
$data = $event->getData();
$form = $event->getForm();
if (null === $data) {
return;
}
/**
* Le composant PropertyAccess fournit des fonctions pour lire
* et écrire depuis/dans un objet ou un tableau en une simple chaîne de caractères.
*/
$accessor = PropertyAccess::getPropertyAccessor();
$sector1 = $accessor->getValue($data, 'sector');
$sector = $this->em->getRepository('BiginfoAdminBundle:Sector')
->findOneBy(array('name' => $sector1));
$delegation = ($sector) ? $sector->getDelegation() : null;
$gouvernaurat_id = ($delegation) ? $delegation->getGouvernaurat()->getId() : null;
$this->addDelegationForm($form, $gouvernaurat_id, $delegation);
}
public function preSubmit(FormEvent $event) {
$data = $event->getData();
$form = $event->getForm();
$gouvernaurat_id = array_key_exists('gouvernaurat', $data) ? $data['gouvernaurat'] : null;
$this->addDelegationForm($form, $gouvernaurat_id);
}
}
我遇到了同样的问题,但提到这个问题 #5694 你必须在父表单中设置 'prototype' => false。