Meu aplicativo atualmente passa dados para meu tipo de formulário usando o construtor, conforme recomendado nesta resposta . No entanto, o guia de atualização do Symfony 2.8 informa que a passagem de uma instância de tipo para a createForm
função está obsoleta:
Passar instâncias de tipo para Form :: add (), FormBuilder :: add () e os métodos FormFactory :: create * () está obsoleto e não será mais suportado no Symfony 3.0. Passe o nome de classe totalmente qualificado do tipo.
Before: $form = $this->createForm(new MyType()); After: $form = $this->createForm(MyType::class);
Visto que não consigo transmitir dados com o nome de classe totalmente qualificado, existe uma alternativa?
Respostas:
Isso quebrou alguns de nossos formulários também. Eu consertei passando os dados personalizados pelo resolvedor de opções.
No seu formulário, digite:
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, ]); }
Então, quando você criar o formulário em seu controlador, passe-o como uma opção em vez de no construtor:
$form = $this->createForm(ProfileEditType::class, $profile, [ 'trait_choices' => $traitChoices, ]);
fonte
Aqui pode ser usada outra abordagem - injetar serviço para recuperar dados.
Exemplo:
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' ]); } }
fonte
No caso de alguém estar usando as funções 'createNamedBuilder' ou 'createNamed' do serviço form.factory, aqui está o trecho sobre como definir e salvar os dados usando-o. Você não pode usar o campo 'dados' (deixe nulo) e você deve definir os dados / entidades passados como
$options
valor.Eu também incorporei instruções @sarahg sobre como usar as opções setAllowedTypes () e setRequired () e parece funcionar bem, mas primeiro você precisa definir o campo com setDefined ()
Também dentro do formulário, se você precisar que os dados sejam configurados, lembre-se de adicioná-los ao campo 'dados'.
No controlador, estou usando getBlockPrefix, pois getName foi preterido em 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) );
Formato:
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', ) ) ... }
fonte
Veja como passar os dados para um formulário embutido para qualquer pessoa usando Symfony 3. Primeiro faça exatamente o que @sekl delineado acima e depois faça o seguinte:
Em seu FormType principal
Passe a var para o formulário incorporado usando ' entry_options '
->add('your_embedded_field', CollectionType::class, array( 'entry_type' => YourEntityType::class, 'entry_options' => array( 'var' => $this->var )))
Em seu FormType incorporado
Adicione a opção ao optionsResolver
public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(array( 'data_class' => 'Yourbundle\Entity\YourEntity', 'var' => null )); }
Acesse a variável em sua função buildForm. Lembre-se de definir esta variável antes da função do construtor. No meu caso, precisei filtrar opções com base em um ID específico.
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); })) ; }
fonte