Moja aplikacja obecnie przekazuje dane do mojego typu formularza przy użyciu konstruktora, zgodnie z zaleceniami w tej odpowiedzi . Jednak przewodnik aktualizacji Symfony 2.8 radzi, że przekazywanie instancji typu do createForm
funkcji jest przestarzałe:
Przekazywanie instancji typu do metod Form :: add (), FormBuilder :: add () i FormFactory :: create * () jest przestarzałe i nie będzie już obsługiwane w Symfony 3.0. Zamiast tego przekaż w pełni kwalifikowaną nazwę klasy typu.
Before: $form = $this->createForm(new MyType()); After: $form = $this->createForm(MyType::class);
Widząc, że nie mogę przekazać danych przy użyciu w pełni kwalifikowanej nazwy klasy, czy istnieje alternatywa?
Odpowiedzi:
To również złamało niektóre z naszych form. Naprawiłem to, przekazując niestandardowe dane przez program rozpoznawania opcji.
W swoim formularzu wpisz:
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, ]); }
Następnie, kiedy tworzysz formularz w swoim kontrolerze, przekaż go jako opcję zamiast w konstruktorze:
$form = $this->createForm(ProfileEditType::class, $profile, [ 'trait_choices' => $traitChoices, ]);
źródło
Tutaj można zastosować inne podejście - wstrzyknąć usługę do pobierania danych.
Przykład:
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' ]); } }
źródło
W przypadku, gdy ktoś korzysta z funkcji „createNamedBuilder” lub „createNamed” z usługi form.factory, oto krótki opis sposobu ustawiania i zapisywania danych za ich pomocą. Nie możesz użyć pola „data” (pozostaw to puste) i musisz ustawić przekazane dane / encje jako
$options
wartość.Dodałem również instrukcje @sarahg dotyczące używania opcji setAllowedTypes () i setRequired () i wydaje się, że działa dobrze, ale najpierw musisz zdefiniować pole za pomocą setDefined ()
Również wewnątrz formularza, jeśli potrzebujesz ustawić dane, pamiętaj, aby dodać je do pola „dane”.
W kontrolerze używam getBlockPrefix, ponieważ getName zostało wycofane w wersji 2.8 / 3.0
Kontroler:
/* * @var $builder Symfony\Component\Form\FormBuilderInterface */ $formTicket = $this->get('form.factory')->createNamed($tasksPerformedForm->getBlockPrefix(), TaskAddToTicket::class, null, array('ticket'=>$ticket) );
Formularz:
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', ) ) ... }
źródło
Oto jak przekazać dane do osadzonego formularza dla każdego, kto używa Symfony 3. Najpierw zrób dokładnie to, co @sekl opisał powyżej, a następnie wykonaj następujące czynności:
W swoim podstawowym FormType
Przekaż zmienną do osadzonego formularza za pomocą „ entry_options ”
->add('your_embedded_field', CollectionType::class, array( 'entry_type' => YourEntityType::class, 'entry_options' => array( 'var' => $this->var )))
W Twoim Embedded FormType
Dodaj opcję do optionsResolver
public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(array( 'data_class' => 'Yourbundle\Entity\YourEntity', 'var' => null )); }
Uzyskaj dostęp do zmiennej w funkcji buildForm. Pamiętaj, aby ustawić tę zmienną przed funkcją budującą. W moim przypadku musiałem filtrować opcje na podstawie określonego identyfikatora.
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); })) ; }
źródło