Symfony5.2 CollectionType嵌套表单报期望DocumentDTO实例错误如何解决
问题根因
表单视图数据期望为"App\Entity\DTO\DocumentDTO"类型实例,但实际传入的是数组
这个错误的直接原因是你在AvisType的CollectionType配置中,错误覆盖了entry_options的data选项:你把父表单的配置数组$options直接赋值给了子表单DocumentType的data,导致Symfony本该给DocumentType传入DocumentDTO实例,实际却收到了配置数组。
修复步骤
1. 修改AvisType的CollectionType配置
删除错误的data覆盖,改为直接传递自定义参数dataPostAvis,同时配置empty_data保证新增集合项时自动生成DocumentDTO实例:
->add('documents', CollectionType::class, [ 'entry_type' => DocumentType::class, 'entry_options' => [ // 删掉错误的'data' => $options, 直接传递你需要的参数 'dataPostAvis' => $options['dataPostAvis'], ], 'prototype' => true, 'allow_add' => true, 'by_reference' => false, // 新增配置:新增集合项时自动创建DocumentDTO实例 'empty_data' => function (FormInterface $form) { return new DocumentDTO(); }, ])
2. 调整DocumentType的参数获取和配置
首先修改DocumentType的configureOptions方法,明确声明允许接收dataPostAvis参数:
public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ 'data_class' => DocumentDTO::class, 'dataPostAvis' => null, ]); // 可选:添加类型校验保证传入的参数符合要求 $resolver->setAllowedTypes('dataPostAvis', DataAvis::class); }
然后修改buildForm中获取choices的逻辑,直接从$options取dataPostAvis,不需要再从data里嵌套获取:
->add('nomTypeDocument', ChoiceType::class, [ 'label' => "Type de document", 'required' => false, // 直接取options里的dataPostAvis,不需要走['data'] 'choices' => $options['dataPostAvis']->nomTypeDocument, 'choice_label' => function ($choice) { return $choice->libNom; }, 'setter' => function(DocumentDTO &$documentDto, NomenclatureDTO $nomenclatureDto) { if ($nomenclatureDto) { $documentDto->nomTypeDocument = $nomenclatureDto->idNom; } } ]) // nomTypeProducteurDoc字段也做同样修改 ->add('nomTypeProducteurDoc', ChoiceType::class, [ 'label' => "Type de producteur du document", 'required' => false, 'choices' => $options['dataPostAvis']->nomTypeProducteurDoc, // 其余配置保持不变 ])
3. 优化DocumentDTO属性初始化
避免后续出现未初始化的类型错误,给DocumentDTO的属性添加默认值:
<?php namespace App\Entity\DTO; class DocumentDTO { public string $fileId = ''; public string $folderId = ''; public string $dtProduction = ''; public string $idActeurProducteur = ''; public array $idsPersonnesProductrices = []; public int $nomTypeDocument = 0; public int $nomTypeProducteurDoc = 0; }
以上修改完成后,DocumentType的data_class可以保留为DocumentDTO::class,不需要设为null,动态新增集合项的功能也能正常运行。
内容的提问来源于stack exchange,提问作者Zabon
相关产品推荐
相关产品推荐

