2013-04-05 7 views
6

Czekam na wypełnienie pola wyboru w symfony2 wartościami z niestandardowego zapytania. Starałem się uprościć jak najwięcej.symfony2 - dodawanie opcji z bazy danych

Controller

class PageController extends Controller 
{ 

    public function indexAction() 
    { 
     $fields = $this->get('fields'); 
     $countries = $fields->getCountries(); // returns a array of countries e.g. array('UK', 'France', 'etc') 
     $routeSetup = new RouteSetup(); // this is the entity 
     $routeSetup->setCountries($countries); // sets the array of countries 

     $chooseRouteForm = $this->createForm(new ChooseRouteForm(), $routeSetup); 


     return $this->render('ExampleBundle:Page:index.html.twig', array(
     'form' => $chooseRouteForm->createView() 
    )); 

    } 
} 

ChooseRouteForm

class ChooseRouteForm extends AbstractType 
{ 

    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 

    // errors... ideally I want this to fetch the items from the $routeSetup object 
    $builder->add('countries', 'choice', array(
     'choices' => $this->routeSetup->getCountries() 
    )); 

    } 

    public function getName() 
    { 
    return 'choose_route'; 
    } 
} 

Odpowiedz

18

Można przekazać wyborów do formularza za pomocą ..

$chooseRouteForm = $this->createForm(new ChooseRouteForm($routeSetup), $routeSetup); 

Następnie w formularzu ..

private $countries; 

public function __construct(RouteSetup $routeSetup) 
{ 
    $this->countries = $routeSetup->getCountries(); 
} 

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $builder->add('countries', 'choice', array(
     'choices' => $this->countries, 
    )); 
} 

Poprawiony (i poprawa) dla 2.8+

Po pierwsze naprawdę nie trzeba przechodzić w państwach jako część obiektu trasy, o ile nie będą przechowywane w DB.

Jeśli przechowujesz dostępne kraje w DB, możesz użyć detektora zdarzeń. Jeśli nie (lub jeśli nie chcesz używać odbiornika), możesz dodać kraje w obszarze opcji.

Korzystanie z opcji

W regulatorze ..

$chooseRouteForm = $this->createForm(
    ChooseRouteForm::class, 
    // Or the full class name if using < php 5.5 
    $routeSetup, 
    array('countries' => $fields->getCountries()) 
); 

A w formularzu ..

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $builder->add('countries', 'choice', array(
     'choices' => $options['countries'], 
    )); 
} 

public function configureOptions(OptionsResolver $resolver) 
{ 
    $resolver 
     ->setDefault('countries', null) 
     ->setRequired('countries') 
     ->setAllowedTypes('countries', array('array')) 
    ; 
} 

Korzystanie słuchacza (w przypadku krajów Tablica jest dostępny w modelu)

W regulatorze ..

$chooseRouteForm = $this->createForm(
    ChooseRouteForm::class, 
    // Or the full class name if using < php 5.5 
    $routeSetup 
); 

A w formularzu ..

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $builder 
     ->addEventListener(FormEvents::PRE_SET_DATA, function(FormEvent $event) { 
      $form = $event->getForm(); 
      /** @var RouteSetup $routeSetup */ 
      $routeSetup = $event->getData(); 

      if (null === $routeSetup) { 
       throw new \Exception('RouteSetup must be injected into form'); 
      } 

      $form 
       ->add('countries', 'choice', array(
        'choices' => $routeSetup->getCountries(), 
       )) 
      ; 
     }) 
    ; 
} 
+1

Tak, jak z Symfony 2.8, jest przestarzałe, aby przejść w instancji klasy formularza. Teraz musisz przekazać w pełni kwalifikowaną nazwę klasy. Co oznacza, że ​​nie można używać konstruktora ... To jest do bani, ponieważ nie chcę ładować opcji z kontrolera, tak jak w moim przypadku, to pole wyboru jest używane od WIELU kontrolerów i miałoby sens konstruować wybory w klasie formularza, jak jednak uzyskać menedżera doktryny do klasy formularza bez korzystania z opcji lub usług ...? włamać się, włamać się, chyba że czegoś mi brakuje, proszę tak powiedzieć. – Prof83

+1

Szczerze mówiąc, to nie było najlepsze podejście. Zaktualizuję. – qooplmao

+0

Bez obaw, Twój post był 2013, a 2.8 jest jak kilka miesięcy temu. Dzięki za aktualizację ... Teraz mogę się z nim teraz bawić – Prof83

10

nie mogę skomentować lub downvote jeszcze, więc będę po prostu odpowiedz na odpowiedź Qoop tutaj: Proponowane przez ciebie propozycje będą działać, chyba że zaczniesz używać swojej klasy typu formularza jako usługi. Powinieneś zasadniczo unikać dodawania danych do obiektu typu formularza za pośrednictwem konstruktora.

Pomyśl typu forma klasa jak klasy - to rodzaj opisu formularza. Po utworzeniu instancji formularza (przez jej zbudowanie) otrzymasz formularz obiektu formularza utworzonego przez opis w typie formularza, a następnie wypełniony danymi.

Spójrz na to: http://www.youtube.com/watch?v=JAX13g5orwo - ta sytuacja jest opisana około 31 minut prezentacji.

Powinieneś użyć zdarzenia FormEvents :: PRE_SET_DATA i manipulować polami po wstrzyknięciu danych. Zobacz: http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html#customizing-your-form-based-on-the-underlying-data

+1

Co to jest za korzyść? Dlaczego nie sprawdzić, czy ustawiono Form Data '$ routesetup'? A jeśli nie, nie dodawaj pola/rzuć niezły błąd? – user2019515

+0

To było najlepsze podejście, po prostu poprawiłem kod w pytaniu, aby działał, a nie "poprawił" go. Zaktualizowałem teraz swoją odpowiedź za pomocą wspomnianego podejścia "PRE_SET_DATA" i innego (z powodu nowego komentarza, w przeciwieństwie do tego, że jestem szalonym, który ponownie odczytuje moją odpowiedź sprzed 2 lub więcej lat). – qooplmao

Powiązane problemy