我有一个表单类型,其他表单类型包括他的一个字段中的第一个。 第二种表单类型用于显示实体列表
第一种表格类型:
<?php
namespace Test\GameBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Doctrine\ORM\EntityRepository;
class CityType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('nameEn')
->add('latitude')
->add('longitude')
->add('country','entity',array(
'class' => 'GeoQuizzGameBundle:Country',
'property' => 'nameEn',
'query_builder' => function(EntityRepository $er) {
return $er->createQueryBuilder('c')
->orderBy('c.nameEn', 'ASC');
},
))
;
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Test\GameBundle\Entity\City'
));
}
/**
* @return string
*/
public function getName()
{
return 'test_gamebundle_city';
}
}
第二个实体:
namespace Test\AdminBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Test\GameBundle\Form\CityType;
class CityListType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('cities','collection', array(
'type'=>new CityType(),
'allow_add' => true,
'by_reference' => false
))
;
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Test\AdminBundle\Entity\CityList'
));
}
/**
* @return string
*/
public function getName()
{
return 'test_adminbundle_citylist';
}
}
和控制器中的表单创建:
public function listAction(Request $request)
{
$cityRepository = $this->getDoctrine()->getRepository("GeoQuizzGameBundle:City");
//get continents
$cities = $cityRepository->findBy(
array(),
array('nameEn' => 'ASC')
);
$cityList = new CityList();
foreach($cities as $city){
$cityList->addCity($city);
}
$form = $this->createForm(new CityListType(),$cityList);
$form->handleRequest($request);
if($form->isValid()){
$em = $this->getDoctrine()->getManager();
foreach ($cityList->getCities() as $city){
if(!$this->isCity($cities, $city)){
$em->persist($city);
}
}
$em->flush();
return $this->redirect($this->generateUrl('geo_quizz_admin_city_list'));
}
return $this->render('GeoQuizzAdminBundle:City:list.html.twig',array(
'form' => $form->createView()
));
}
我有124个字段的请求,因为国家/地区列表在每一行都是重新查询,是否有防止它的解决方案?
我可以在控制器中执行查询并将我的国家/地区数组作为表单类型的参数传递,是否干净?
答案 0 :(得分:1)
您可以使用choice
字段类型而不是entity
。您需要做的只是choices
参数,其中包含您的国家/地区列表。
$countryChoices
是一个国家/地区的关联数组,您可以抓取一次并在buildForm
方法中使用它。我这样做的方法是将表单作为服务,并将ObjectManager
传递给contructor:
<强> services.yml:强>
services:
your_form:
class: Test\GameBundle\Form\CityListType
arguments: [@doctrine.orm.entity_manager]
tags:
- { name: form.type, alias: yourFormAlias }
您的CityType
班级:
class CityType extends AbstractType
{
/**
* @param ObjectManager $objectManager
*/
public function __construct(ObjectManager $objectManager)
{
$this->objectManager = $objectManager;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$countryChoices = array();
//by using result cache your query would be performed only once
$countries = $this->objectManager
->getRepository('GeoQuizzGameBundle:Country')
->createQueryBuilder('c')
->orderBy('c.nameEn', 'ASC')
->getQuery()
->useResultCache(true)
->getResult();
foreach($countries as $country) {
$countryChoices[$country->getId()] = $country->getNameEn();
}
$builder
->add('country','choice',array(
'choices' => $countryChoices,
'label' => 'Country',
))
;
}
}
您还需要像服务一样开始调用您的表单。