symfony2 - 从数据库中添加选择

2021-12-28 00:00:00 drop-down-menu forms php symfony populate

我希望用来自自定义查询的值填充 symfony2 中的选择框.我尽量简化.

I am looking to populate a choice box in symfony2 with values from a custom query. I have tried to simplify as much as possible.

控制器

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

    }
}

选择路由表单

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

推荐答案

您可以使用...将选项传递给您的表单

You could pass the choices to your form using..

$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+ 进行更新(和改进)

首先,除非将国家/地区存储在数据库中,否则您实际上并不需要将它们作为路线对象的一部分传入.

Firstly you don't really need to pass in the countries as part of the route object unless they are going to be stored in the DB.

如果将可用国家/地区存储在数据库中,那么您可以使用事件侦听器.如果没有(或者如果您不想使用侦听器),您可以在选项区域中添加国家/地区.

If storing the available countries in the DB then you can use an event listener. If not (or if you don't want to use a listener) you can add the countries in the options area.

使用选项

在控制器中..

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

使用监听器(如果模型中的国家/地区数组可用)

Using A Listener (If the countries array is available in the model)

在控制器中..

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

相关文章