Mi aplicación actualmente pasa datos a mi tipo de formulario usando el constructor, como se recomienda en esta respuesta . Sin embargo, la guía de actualización de Symfony 2.8 advierte que pasar una instancia de tipo a la createForm
función está en desuso:
Pasar instancias de tipo a Form :: add (), FormBuilder :: add () y los métodos FormFactory :: create * () está obsoleto y ya no será compatible con Symfony 3.0. En su lugar, pase el nombre de clase completamente calificado del tipo.
Before: $form = $this->createForm(new MyType()); After: $form = $this->createForm(MyType::class);
Dado que no puedo pasar datos con el nombre de clase completamente calificado, ¿hay alguna alternativa?
Respuestas:
Esto también rompió algunas de nuestras formas. Lo arreglé pasando los datos personalizados a través del solucionador de opciones.
En su formulario escriba:
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, ]); }
Luego, cuando cree el formulario en su controlador, páselo como una opción en lugar de en el constructor:
$form = $this->createForm(ProfileEditType::class, $profile, [ 'trait_choices' => $traitChoices, ]);
fuente
Aquí se puede utilizar otro enfoque: servicio de inyección para recuperar datos.
Ejemplo:
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' ]); } }
fuente
En caso de que alguien esté usando las funciones 'createNamedBuilder' o 'createNamed' del servicio form.factory, aquí está el fragmento de cómo configurar y guardar los datos usándolo. No puede usar el campo 'datos' (déjelo nulo) y debe establecer los datos / entidades pasados como
$options
valor.También incorporé instrucciones de @sarahg sobre el uso de las opciones setAllowedTypes () y setRequired () y parece funcionar bien, pero primero debes definir el campo con setDefined ()
También dentro del formulario, si necesita que se establezcan los datos, recuerde agregarlos al campo 'datos'.
En Controller estoy usando getBlockPrefix ya que getName quedó obsoleto en 2.8 / 3.0
Controlador:
/* * @var $builder Symfony\Component\Form\FormBuilderInterface */ $formTicket = $this->get('form.factory')->createNamed($tasksPerformedForm->getBlockPrefix(), TaskAddToTicket::class, null, array('ticket'=>$ticket) );
Formar:
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', ) ) ... }
fuente
Aquí se explica cómo pasar los datos a un formulario incrustado para cualquier persona que use Symfony 3. Primero haga exactamente lo que @sekl describió anteriormente y luego haga lo siguiente:
En su FormType principal
Pase la var al formulario incrustado usando ' entry_options '
->add('your_embedded_field', CollectionType::class, array( 'entry_type' => YourEntityType::class, 'entry_options' => array( 'var' => $this->var )))
En su FormType incrustado
Agregue la opción a optionsResolver
public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(array( 'data_class' => 'Yourbundle\Entity\YourEntity', 'var' => null )); }
Acceda a la variable en su función buildForm. Recuerde establecer esta variable antes de la función de constructor. En mi caso, necesitaba filtrar opciones en función de una identificación específica.
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); })) ; }
fuente