В настоящее время мое приложение передает данные в мой тип формы с помощью конструктора, как рекомендовано в этом ответе . Однако руководство по обновлению Symfony 2.8 сообщает, что передача экземпляра типа createForm
функции устарела:
Передача экземпляров типов в методы Form :: add (), FormBuilder :: add () и FormFactory :: create * () устарела и больше не будет поддерживаться в Symfony 3.0. Вместо этого передайте полное имя класса типа.
Before: $form = $this->createForm(new MyType()); After: $form = $this->createForm(MyType::class);
Поскольку я не могу передавать данные с полным именем класса, есть ли альтернатива?
Ответы:
Это также нарушило некоторые наши формы. Я исправил это, передав пользовательские данные через преобразователь параметров.
В вашей форме введите:
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, ]); }
Затем, когда вы создаете форму в своем контроллере, передайте ее в качестве опции вместо конструктора:
$form = $this->createForm(ProfileEditType::class, $profile, [ 'trait_choices' => $traitChoices, ]);
источник
Здесь можно использовать другой подход - инъекционный сервис для извлечения данных.
Пример:
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' ]); } }
источник
Если кто-то использует функции createNamedBuilder или createNamed из службы form.factory, вот фрагмент о том, как установить и сохранить данные с его помощью. Вы не можете использовать поле 'data' (оставьте это значение null), и вы должны установить переданные данные / объекты как
$options
значение.Я также включил инструкции @sarahg об использовании параметров setAllowedTypes () и setRequired (), и, похоже, он работает нормально, но сначала вам нужно определить поле с помощью setDefined ()
Также внутри формы, если вам нужно установить данные, не забудьте добавить их в поле «данные».
В контроллере я использую getBlockPrefix, поскольку getName устарело в 2.8 / 3.0
Контроллер:
/* * @var $builder Symfony\Component\Form\FormBuilderInterface */ $formTicket = $this->get('form.factory')->createNamed($tasksPerformedForm->getBlockPrefix(), TaskAddToTicket::class, null, array('ticket'=>$ticket) );
Форма:
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', ) ) ... }
источник
Вот как передать данные во встроенную форму для всех, кто использует Symfony 3. Сначала сделайте именно то, что @sekl, описанное выше, а затем сделайте следующее:
В вашем основном FormType
Пропустите вар к встраиваемой форме с использованием « entry_options »
->add('your_embedded_field', CollectionType::class, array( 'entry_type' => YourEntityType::class, 'entry_options' => array( 'var' => $this->var )))
В вашем встроенном FormType
Добавляем опцию в optionsResolver
public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(array( 'data_class' => 'Yourbundle\Entity\YourEntity', 'var' => null )); }
Получите доступ к переменной в вашей функции buildForm. Не забудьте установить эту переменную перед функцией построителя. В моем случае мне нужно было отфильтровать параметры на основе определенного идентификатора.
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); })) ; }
источник