Мое приложение в настоящее время передает данные в мой тип формы с использованием конструктора, как это рекомендовано в этом ответе . Однако руководство по обновлению Symfony 2.8 сообщает, что передача экземпляра createForm
функции createForm
устарела:
Коды экземпляров типа Form :: add (), FormBuilder :: add () и FormFactory :: create * () устарели и больше не будут поддерживаться в Symfony 3.0. Вместо этого передайте полностью квалифицированное имя класса.
- Как использовать ACL для фильтрации списка объектов домена в соответствии с разрешениями определенного пользователя (например, EDIT)?
- Symfony2 - установить security access_control для разрешения только анонимной аутентификации
- Как экспортировать объект как CSV в Symfony?
- Doctrine 2 добавляет новое поле, которое автоматически генерирует значения последовательности
- Тип поля Symfony 2 Entity с выбором и / или добавлением нового
Before: $form = $this->createForm(new MyType()); After: $form = $this->createForm(MyType::class);
Видя, как я не могу передать данные с помощью полностью квалифицированного имени класса, есть ли альтернатива?
Это нарушило и некоторые наши формы. Я исправил его, передав пользовательские данные через опцию resolver.
В вашей форме:
public function buildForm(FormBuilderInterface $builder, array $options) { $this->traitChoices = $options['trait_choices']; $builder ->add('name', TextType::class, ['label' => 'L_PROFILE_EDIT_NAME', 'required' => false]) ... ->add('figure_type', ChoiceType::class, [ 'label' => 'L_PROFILE_EDIT_FIGURETYPE', 'mapped' => false, 'choices' => $this->traitChoices['figure_type'] ]) ... ; } /** * {@inheritdoc} */ public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(array( 'data_class' => 'Foo\BarBundle\Entity\Profile', 'trait_choices' => null, )); }
Затем, когда вы создаете форму в своем контроллере, передайте ее как вариант, а не в конструкторе:
$form = $this->createForm(ProfileEditType::class, $profile, array( 'action' => $this->generateUrl('profile_update'), 'method' => 'PUT', 'trait_choices' => $traitChoices, ));
В случае, если кто-либо использует функции createNamedBuilder или createNamed из сервиса form.factory, здесь приведен фрагмент того, как установить и сохранить данные с его помощью. Вы не можете использовать поле данных (оставить это значение 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
Передайте var во встроенную форму, используя ' entry_options '
->add('your_embedded_field', CollectionType::class, array( 'entry_type' => YourEntityType::class, 'entry_options' => array( 'var' => $this->var )))
В вашем встроенном типе формы
Добавьте опцию в опцииРезольвер
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); })) ; }
Здесь можно использовать другой подход – внедрить службу для извлечения данных.
Пример:
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' ]); } }