当我尝试呈现表单AvisType
时,我遇到了这个错误:
表单的视图数据应为“App\Entity\DTO\DocumentDTO”,但它是“数组”。可以通过将“data_class”选项设置为null或添加将“数组”转换为“App\Entity\DTO\DocumentDTO”示例的视图转换器Transformer来避免此错误。
我有一个AvisType
表单:
<?php
namespace App\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use App\Entity\DTO\AvisDTO;
use App\Entity\DTO\NomenclatureDTO;
use App\Entity\DTO\DataFormMapper\DataAvis;
use App\Entity\DTO\DocumentDTO;
class AvisType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('nomAuteur', TextType::class, [
'label' => "Nom",
])
->add('prenomAuteur', TextType::class, [
'label' => "Prénom"
])
->add('boEstTacite', ChoiceType::class, [
'required' => true,
'label' => "L'avis est-il tacite ?",
'label_attr' => [
'class' => "font-weight-bold"
],
'expanded' => true,
'multiple' => false,
'choices' => [
'Oui' => true,
'Non' => false,
],
])
->add('nomNatureAvisRendu', ChoiceType::class, [
'label' => "Nature de l'avis rendu",
'required' => false,
'choices' => $options['dataPostAvis']->nomNatureAvisRendu,
'choice_label' => function ($choice) {
return $choice->libNom;
},
'setter' => function (AvisDTO &$avisDto, NomenclatureDTO $nomenclatureDto) {
if ($nomenclatureDto) {
$avisDto->nomNatureAvisRendu = $nomenclatureDto->idNom;
}
}
])
->add('nomTypeAvis', ChoiceType::class, [
'label' => "Type d'avis",
'required' => false,
'choices' => $options['dataPostAvis']->nomTypeAvis,
'choice_label' => function ($choice) {
return $choice->libNom;
},
'setter' => function (AvisDTO &$avisDto, NomenclatureDTO $nomenclatureDto) {
if ($nomenclatureDto) {
$avisDto->nomTypeAvis = $nomenclatureDto->idNom;
}
}
])
->add('documents', CollectionType::class, [
'entry_type' => DocumentType::class,
'entry_options' => [
'data' => $options,
],
'prototype' => true,
'allow_add' => true,
'by_reference' => false,
])
->add('txAvis', TextareaType::class, [
'required' => true,
'attr' => [
'placeholder' => "Avis favorable avec prescriptions. \nPremière prescription : Les volets doivent être en bois"
]
])
->add('txFondementAvis', TextareaType::class, [
'attr' => [
'placeholder' => "L'avis de l'ABF est rendu en application de l'article R. 425-30 du Code de l'urbanisme."
]
])
->add('txHypotheses', TextareaType::class, [
'attr' => [
'placeholder' => "Dans l'hypothèse où la puissance électrique nécessaire est de x alors le coût de raccordement est de y"
]
])
->add('txQualiteAuteur', TextareaType::class, [
'attr' => [
'placeholder' => "Qualité"
]
])
->add('Envoyer', SubmitType::class);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => AvisDTO::class,
'dataPostAvis' => DataAvis::class,
]);
}
}
这是我的AvisDTO
类:
<?php
namespace App\Entity\DTO;
use Symfony\Component\Serializer\Annotation\Groups;
use Doctrine\Common\Collections\ArrayCollection;
class AvisDTO
{
public string $dtAvis;
public string $dtEmission;
public string $idActeurAuteur;
public string $nomAuteur;
public string $prenomAuteur;
public bool $boEstTacite;
public ArrayCollection $documents;
public string $idConsultation;
public array $idsPieces;
public int $nomNatureAvisRendu;
public int $nomTypeAvis;
public string $txAvis;
public string $txFondementAvis;
public string $txHypotheses;
public string $txQualiteAuteur;
public function __construct()
{
$this->documents = new ArrayCollection();
}
}
最后是我的DocumentType
:
<?php
namespace App\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Constraints\File;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use App\Entity\DTO\DocumentDTO;
use App\Entity\DTO\NomenclatureDTO;
class DocumentType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
// dd($options);
$builder
->add('nomTypeDocument', ChoiceType::class, [
'label' => "Type de document",
'required' => false,
'choices' => $options['data']['dataPostAvis']->nomTypeDocument,
'choice_label' => function ($choice) {
return $choice->libNom;
},
'setter' => function(DocumentDTO &$documentDto, NomenclatureDTO $nomenclatureDto) {
if ($nomenclatureDto) {
$documentDto->nomTypeDocument = $nomenclatureDto->idNom;
}
}
])
->add('nomTypeProducteurDoc', ChoiceType::class, [
'label' => "Type de producteur du document",
'required' => false,
'choices' => $options['data']['dataPostAvis']->nomTypeProducteurDoc,
'choice_label' => function ($choice) {
return $choice->libNom;
},
'setter' => function(DocumentDTO &$documentDto, NomenclatureDTO $nomenclatureDto) {
if ($nomenclatureDto) {
$documentDto->nomTypeProducteurDoc = $nomenclatureDto->idNom;
}
}
])
->add('upload_file', FileType::class, [
'label' => false,
'mapped' => false,
'attr' => [
'data-dossier-target' => 'fileName',
'data-action' => 'change->dossier#getFileName'
],
'constraints' => [
new File([
'mimeTypes' => [
'application/pdf', //PDF
'application/msword', //DOC
'application/vnd.openxmlformats-officedocument.wordprocessingml.document', //DOCX
'application/vnd.oasis.opendocument.spreadsheet', //ODS
'application/vnd.oasis.opendocument.text', //ODT
'application/vnd.ms-excel', //XLS
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', //XLSX
'image/bmp', //BMP
'image/x-ms-bmp', //BMP
'image/png', //PNG
'image/gif', //GIF
'image/tiff', //TIF & TIFF
'image/jpeg', //JPEG & JPG
'image/dib', //DIB
],
'mimeTypesMessage' => "Ce document n'est pas valide.",
])
]
])
->add('fileId', HiddenType::class)
->add('folderId', HiddenType::class)
->add('dtProduction', HiddenType::class)
->add('idActeurProducteur', HiddenType::class)
->add('idsPersonnesProductrices', HiddenType::class);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => DocumentDTO::class,
'dataPostAvis' => DataAvisType::class,
]);
}
}
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;
public int $nomTypeProducteurDoc;
}
我的控制器:
$avis = new AvisDTO();
$avis->idConsultation = $idConsultation;
$avis->idActeurAuteur = $idActeurAppelant; // A verifier
$avis->idsPieces = $idPiecesList;
$form = $this->createForm(AvisType::class, $avis, $options);
$form->handleRequest($request);
所以我理解的是,Symfony不能创建DocumentType
表单,因为它从AvisType
接收数组。我需要这个嵌套表单是“动态的”,我的用户必须能够添加新的文档到AvisType
。
我一直在关注这个文档:https://symfony.com/doc/current/form/form_collections.html#allowing-new-tags-with-the-prototype
如何在不将DocumentType
data_class
设置为null
的情况下解决此错误?
1条答案
按热度按时间uqxowvwt1#
您可以在DocumentDTO类中添加方法来转换数组。如果您这样做,则该类将如下所示:
您可以在DocumentType类中添加一个viewTransformer,在其中使用dto类中的方法来转换数据对象。如果您这样做,App\Form\DocumentType将如下所示:
现在,每次加载表单视图时,都会调用Transformer,并将数据转换为正确的格式。您应该更改我建议的转换方法,以更好地满足项目的需要。