symfony2 – добавление выбора из базы данных

Я хочу заполнить поле выбора в symfony2 со значениями из пользовательского запроса. Я старался как можно больше упростить.

контроллер

class PageController extends Controller { public function indexAction() { $fields = $this->get('fields'); $countries = $fields->getCountries(); // returns a array of countries eg 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'; } } 

Вы можете передать выбор в свою форму, используя ..

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

Тогда в вашей форме ..

 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, )); } 

Обновлено (и улучшено) для 2.8+

Во-первых, вам не обязательно проходить в странах как часть объекта маршрута, если они не будут храниться в БД.

Если вы сохраняете доступные страны в БД, вы можете использовать прослушиватель событий. Если нет (или если вы не хотите использовать прослушиватель), вы можете добавить страны в область опций.

Использование опций

В контроллере ..

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

И в твоей форме ..

 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')) ; } 

Использование A Listener (Если массив стран доступен в модели)

В контроллере ..

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

И в твоей форме ..

 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(), )) ; }) ; } 

Я не могу комментировать или понижать пока, поэтому я просто отвечу на ответ Qoop здесь: то, что вы предложили, будет работать, если вы не начнете использовать свой тип типа типа в качестве службы. Обычно вы должны избегать добавления данных в объект типа формы через конструктор.

Подумайте о классе типа типа, например, о классе – это своеобразное описание вашей формы. Когда вы создаете экземпляр формы (путем ее создания), вы получаете объект формы, который создается по описанию в типе формы, а затем заполняется данными.

Взгляните на это: http://www.youtube.com/watch?v=JAX13g5orwo – эта ситуация описана примерно через 31 минуту представления.

Вы должны использовать событие формы FormEvents :: PRE_SET_DATA и манипулировать полями, когда форма вводится с данными. См .: http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html#customizing-your-form-based-on-the-underlying-data