我有一个表单类型和另一个表单类型包括第一个在他的一个字段。第二种表单类型用于显示实体列表
第一个表单类型:
<?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()
));
}
我有196个请求124个字段,因为国家列表是查询每一行,有一个解决方案来防止它吗?
我可以在控制器中进行查询,并通过我的国家数组作为表单类型的参数,它是干净的吗?
您可以使用choice
字段类型代替entity
。所有你需要做的是有choices
参数包含你的国家列表。
$countryChoices
是一个国家的关联数组,您可以获取一次并在buildForm
方法中使用它。我要这样做的方式是使您的表单服务,并传递ObjectManager
构造器:
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',
))
;
}
}
您还需要开始像调用服务一样调用您的表单