Mon application transmet actuellement des données à mon type de formulaire à l'aide du constructeur, comme recommandé dans cette réponse . Cependant, le guide de mise à niveau de Symfony 2.8 indique que le passage d'une instance de type à la createForm
fonction est obsolète:
Passer des instances de type à Form :: add (), FormBuilder :: add () et les méthodes FormFactory :: create * () est obsolète et ne sera plus pris en charge dans Symfony 3.0. Passez plutôt le nom de classe complet du type.
Before: $form = $this->createForm(new MyType()); After: $form = $this->createForm(MyType::class);
Étant donné que je ne peux pas transmettre de données avec le nom de classe complet, existe-t-il une alternative?
Réponses:
Cela a également brisé certaines de nos formes. Je l'ai corrigé en passant les données personnalisées via le résolveur d'options.
Dans votre type de formulaire:
public function buildForm(FormBuilderInterface $builder, array $options) { $this->traitChoices = $options['trait_choices']; $builder ... ->add('figure_type', ChoiceType::class, [ 'choices' => $this->traitChoices, ]) ... ; } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ 'trait_choices' => null, ]); }
Ensuite, lorsque vous créez le formulaire dans votre contrôleur, passez-le en tant qu'option au lieu de dans le constructeur:
$form = $this->createForm(ProfileEditType::class, $profile, [ 'trait_choices' => $traitChoices, ]);
la source
Ici, une autre approche peut être utilisée - un service d'injection pour récupérer des données.
Exemple:
services: app.any.manager: class: AppBundle\Service\AnyManager form.my.type: class: AppBundle\Form\MyType arguments: ["@app.any.manager"] tags: [ name: form.type ]
<?php namespace AppBundle\Form; use AppBundle\Service\AnyManager; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; class MyType extends AbstractType { /** * @var AnyManager */ protected $manager; /** * MyType constructor. * @param AnyManager $manager */ public function __construct(AnyManager $manager) { $this->manager = $manager; } public function buildForm(FormBuilderInterface $builder, array $options) { $choices = $this->manager->getSomeData(); $builder ->add('type', ChoiceType::class, [ 'choices' => $choices ]) ; } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ 'data_class' => 'AppBundle\Entity\MyData' ]); } }
la source
Si quelqu'un utilise les fonctions 'createNamedBuilder' ou 'createNamed' du service form.factory, voici l'extrait de code expliquant comment définir et enregistrer les données en l'utilisant. Vous ne pouvez pas utiliser le champ 'data' (laissez ce champ nul) et vous devez définir les données / entités transmises comme
$options
valeur.J'ai également incorporé des instructions @sarahg sur l'utilisation des options setAllowedTypes () et setRequired () et cela semble fonctionner correctement, mais vous devez d'abord définir le champ avec setDefined ()
Aussi à l'intérieur du formulaire si vous avez besoin que les données soient définies, n'oubliez pas de les ajouter au champ «données».
Dans Controller, j'utilise getBlockPrefix car getName était obsolète dans 2.8 / 3.0
Manette:
/* * @var $builder Symfony\Component\Form\FormBuilderInterface */ $formTicket = $this->get('form.factory')->createNamed($tasksPerformedForm->getBlockPrefix(), TaskAddToTicket::class, null, array('ticket'=>$ticket) );
Forme:
public function configureOptions(OptionsResolver $resolver) { $resolver->setDefined('ticket'); $resolver->setRequired('ticket'); $resolver->addAllowedTypes('ticket', Ticket::class); $resolver->setDefaults(array( 'translation_domain'=>'AcmeForm', 'validation_groups'=>array('validation_group_001'), 'tasks' => null, 'ticket' => null, )); } public function buildForm(FormBuilderInterface $builder, array $options) { $this->setTicket($options['ticket']); //This is required to set data inside the form! $options['data']['ticket']=$options['ticket']; $builder ->add('ticket', HiddenType::class, array( 'data_class'=>'acme\TicketBundle\Entity\Ticket', ) ) ... }
la source
Voici comment transmettre les données à un formulaire intégré pour toute personne utilisant Symfony 3. Commencez par faire exactement ce que @sekl a décrit ci-dessus, puis procédez comme suit:
Dans votre FormType principal
Passez le var au formulaire incorporé en utilisant ' entry_options '
->add('your_embedded_field', CollectionType::class, array( 'entry_type' => YourEntityType::class, 'entry_options' => array( 'var' => $this->var )))
Dans votre type de formulaire intégré
Ajouter l'option aux optionsResolver
public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(array( 'data_class' => 'Yourbundle\Entity\YourEntity', 'var' => null )); }
Accédez à la variable dans votre fonction buildForm. N'oubliez pas de définir cette variable avant la fonction de générateur. Dans mon cas, j'avais besoin de filtrer les options en fonction d'un identifiant spécifique.
public function buildForm(FormBuilderInterface $builder, array $options) { $this->var = $options['var']; $builder ->add('your_field', EntityType::class, array( 'class' => 'YourBundle:YourClass', 'query_builder' => function ($er) { return $er->createQueryBuilder('u') ->join('u.entity', 'up') ->where('up.id = :var') ->setParameter("var", $this->var); })) ; }
la source