Symfony 7 带有附加参数的 CollectionType

问题描述 投票:0回答:1

多年后我又回到了 Symfony,我很喜欢这个新版本 7。

我正在努力使用 CollectionType,因为我只需要显示基于主对象的某些字段,但我找不到将参数/选项传递到嵌入表单(CollectionType)的方法。

如果我传递额外的选项,我会收到错误:

An error has occurred resolving the options of the form "Symfony\Component\Form\Extension\Core\Type\CollectionType": The option "category" does not exist.

我有一个基于“活动”实体的表单,并且活动可以有许多动物。 根据活动的类别,动物应该有一些领域,而不是其他领域。

我的想法是将活动的类别传递给子表单,并在那里编写逻辑以添加所需的字段。

怎样才能做到这一点?

这是我的代码:

<?php

namespace App\Form;

use App\Entity\Activity;
use App\Entity\ActivityCategory;
use App\Entity\Animal;
use App\Entity\User;
use App\Form\ActivityAnimalType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class ActivityType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('date')
            ->add('shift')
            ->add('people', EntityType::class, [
                'class' => User::class,
                'multiple' => true,
            ])
            ->add('animals', CollectionType::class, [
                'entry_type' => AnimalType::class,
                'entry_options' => [
                    'label' => false,
                ],
                'category' => $options['category'],
                'allow_add' => true,
                'allow_delete' => true,
                'by_reference' => false,
            ])
            ->add('save', SubmitType::class);
        ;

        if ($options['category'] == 'asilo') {
            $builder->remove('people');
        }
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'data_class' => Activity::class,
            'category' => ActivityCategory::class,
        ]);
    }
}

还有AnimanType

<?php

namespace App\Form;

use App\Entity\Activity;
use App\Entity\ActivityAnimal;
use App\Entity\Animal;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class AnimalType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('quantity')
            ->add('type', ChoiceType::class, [
                'choices'  => [
                    'Full Day' => 1,
                    'Half Day' => 2,
                ],
            ])
        ;
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setRequired(['category']);
        $resolver->setDefaults([
            'data_class' => ActivityAnimal::class,
        ]);
    }
}

虽然将 Activity->category 从控制器传递到主窗体效果很好,但我找不到在嵌入式 CollectionType 中插入相同逻辑的方法。

我尝试将选项传递给 CollectionType,并查看了文档中的所有位置。 我也查看了事件监听器,但没有找到类似的案例。

谢谢!

symfony symfony-forms
1个回答
0
投票

有两件事:

-> 如前所述,“类别”不作为选项存在:) 查看此处的文档。 因此,如果您想在表单上添加类别,您可以添加一个属性(“attr”选项)。

-> 如果您需要搜索数据以获取您选择的类别的动物,您必须在控制器上执行此操作并在选项中传递数据。

例如,在您的控制器中:

$animalCollection = $em->getRepository(Animal::class)->findBy(['category' => $category]);
$form = $this->createForm(ActivityType::class, $activity, ['category' => $category, 'animal_collection' => $animalCollection]);  

以您的形式:

<?php

namespace App\Form;

use App\Entity\Activity;
use App\Entity\ActivityCategory;
use App\Entity\Animal;
use App\Entity\User;
use App\Form\ActivityAnimalType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class ActivityType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('date')
            ->add('shift')
            ->add('people', EntityType::class, [
                'class' => User::class,
                'multiple' => true,
            ])
            ->add('animals', CollectionType::class, [
                'entry_type' => AnimalType::class,
                'entry_options' => [
                    'label' => false,
                ],
              // If you need to keep your category as an attribute in you form
                'attr' => ['category' => $options['category']],
              // Datas from your controller
                'data' =>  $option['animal_collection'],
                'allow_add' => true,
                'allow_delete' => true,
                'by_reference' => false,
            ])
            ->add('save', SubmitType::class);
        ;

        if ($options['category'] == 'asilo') {
            $builder->remove('people');
        }
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'data_class' => Activity::class,
            'category' => null,
            'animal_collection' => null,
        ]); 
    }
}

希望这些对你有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.