Symfony表单EntityType如何按实体ID限定可选选项
问题原因
- EntityType 的
choices参数要求传入实体对象数组,你传入的闭包不会被框架自动执行获取数据,因此配置不生效 - 你编写的闭包没有添加
return关键字,即使手动执行也无法返回宝可梦实例
最优实现方案
使用 EntityType 原生支持的 query_builder 参数自定义查询规则,无需额外传递参数,代码修改如下:
<?php namespace App\Form; use App\Entity\Pokemon; use App\Entity\CatchPokemon; use Doctrine\ORM\EntityRepository; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\OptionsResolver\OptionsResolver; class ChooseStarterType extends AbstractType{ public function buildForm(FormBuilderInterface $builder, array $options){ $builder ->add('pokemonId', EntityType::class,[ 'class' => Pokemon::class, 'choice_label' => 'name', // 自定义查询只返回ID为1、2、3的宝可梦 'query_builder' => function (EntityRepository $er) { return $er->createQueryBuilder('p') ->where('p.id IN (:allowedIds)') ->setParameter('allowedIds', [1,2,3]) ->orderBy('p.name', 'ASC'); }, ]) ; } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ 'data_class' => CatchPokemon::class, ]); } }
可选方案(适用可选ID动态变化场景)
如果可选初始宝可梦需要根据业务逻辑动态调整(比如不同地区初始宝可梦不同),可以通过表单自定义参数传递可选列表:
- 首先修改表单类,新增自定义参数接收宝可梦列表
// 表单类中修改configureOptions方法 public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ 'data_class' => CatchPokemon::class, 'allowed_starters' => [], // 新增自定义参数 ]); }
// buildForm中使用传入的参数作为choices $builder ->add('pokemonId', EntityType::class,[ 'class' => Pokemon::class, 'choice_label' => 'name', 'choices' => $options['allowed_starters'], ]) ;
- 控制器中创建表单时传入查询到的可选宝可梦
// 控制器逻辑示例 $starters = $pokemonRepository->findBy(['id' => [1,2,3]]); $form = $this->createForm(ChooseStarterType::class, $catchPokemon, [ 'allowed_starters' => $starters ]);
内容的提问来源于stack exchange,提问作者Noctissei
相关产品推荐
相关产品推荐

