Symfony:如何将项目的子集从大集合添加到实体类型?

Symfony:如何将项目的子集从大集合添加到实体类型?,symfony,Symfony,一种汽车机油适用于多种车型,但在我的情况下,我们的系统中有数百种车型,我不想将它们全部加载到一个页面,然后,让用户选择特定的车型,最好使用ajax调用按汽车品牌、汽车系列获取车型。用户选择项目的子集合,将这些选定的项目发布到服务器 在表单类型中,我添加了一个如下所示的表单字段,如我们所知,如果我不将其选项设置为空数组,实体字段将获得所有车型,这将导致巨大的性能损失 ->add('applicableModels', 'entity', array(

一种汽车机油适用于多种车型,但在我的情况下,我们的系统中有数百种车型,我不想将它们全部加载到一个页面,然后,让用户选择特定的车型,最好使用ajax调用按汽车品牌、汽车系列获取车型。用户选择项目的子集合,将这些选定的项目发布到服务器

在表单类型中,我添加了一个如下所示的表单字段,如我们所知,如果我不将其选项设置为空数组,实体字段将获得所有车型,这将导致巨大的性能损失

->add('applicableModels', 'entity', array(
                        'class' => 'VMSP\CarBundle\Entity\CarModel',
                        'choices'=>array(),
                        'multiple'=>true,
                        'property_path' => "modelName",
                        'label' => 'vmsp_product.product.form.applicable_model',
                    )
          )

那么,如何从一个大集合中添加一个子集合项,并将这些选定项分配给实体类型呢

简单的答案是,您可以为添加到表单中的每个元素定义自定义查询生成器,即

$data = $builder->getData();
\\...
->add('applicableModels', 'entity', array(
    'class' => 'VMSP\CarBundle\Entity\CarModel',
    'multiple' => true,
    'property_path' => "modelName",
    'label' => 'vmsp_product.product.form.applicable_model',
    'query_builder' => function (EntityRepository $er) use ($data) {
        $qb = $er->createQueryBuilder('e')
                ->where('e.manufacturer IN (:manufacturer)')
                ->setParameter('manufacturer', $data['manufacturer']);
        return $qb->orderBy('e.name');
    },
))
因此,您可能有一种向导,其中用户选择制造商,页面重新加载,显示的汽车只是一个子集

然而,在一个非常相似的情况下,我最终做了一些不同的事情。在表单中,选项设置为空数组。在前端,通过Ajax调用单独的API来填充选项。然后在表单预提交事件中,我用所选选项填充字段

$builder->addEventListener(
        FormEvents::PRE_SUBMIT, function (FormEvent $event) {
        $form = $event->getForm();
        $data = $event->getData();
        if (!empty($data['applicable_model'])) {
            $form->add('applicable_model', 'entity', array(
                'class' => 'VMSP\CarBundle\Entity\CarModel',
                'query_builder' => function (EntityRepository $er) use ($data) {
                    $qb = $er->createQueryBuilder('e')
                        ->where('e.id IN (:applicable_model)')
                        ->setParameter('applicable_model', $data['applicable_model']);
                    return $qb;
                },
            ));
        }

更新:我了解到addEventListener部分可能会被DataTransforme替代,请参见

非常好,这就是我想要的,谢谢,Francesco。@videni很高兴听到这个消息!我刚刚注意到你的更新,我查看了那篇文章,但我不明白为什么将字段类型从实体更改为文本时它会起作用,因为我们需要的是一个集合,而不是一个项目。你有什么想法吗?