繁体   English   中英

减少表单Symfony2中的请求数

[英]Reduce the number of request in form Symfony2

我有一个表单类型,另一个表单类型包括他的一个字段中的第一个。 第二种表单类型用于显示实体列表

第一种表单类型:

<?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个字段有196个请求,因为国家/地区列表在每一行上都进行了重新查询,是否有解决方案来防止它?

我可以在控制器中进行查询,然后将country数组作为表单类型的参数传递,这干净吗?

您可以使用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',
               ))
        ;
    } 
}

您还需要像服务一样开始调用表单。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM