Symfony2的 - 将来自数据库的选择(symfony2 - adding choices fr

2019-08-19 20:37发布

我期待来填充Symfony2的一个选择框使用自定义查询值。 我试图简化尽可能多地。

调节器

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

Answer 1:

你可以通过选择你的形式使用,以..

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

使用侦听 (如果该国阵可在模型中)

在控制器..

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


Answer 2:

我无法评论或downvote呢,所以我就回复Qoop的答案在这里:除非你开始使用你的表单类型类的服务,你提出什么工作。 通常应避免通过构造器将数据添加到您的表单类型的对象。

想想表单类型类与 -它是一种表单的说明。 当您形式的实例 (通过构建它),你得到表单的对象是由表单类型的描述构建,然后填入数据。

看看这个: http://www.youtube.com/watch?v=JAX13g5orwo -这种局面是围绕presentaion的31分钟描述。

您应该使用表单事件FormEvents :: PRE_SET_DATA并在表单与数据注入操作领域。 请参阅: http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html#customizing-your-form-b​​ased-on-the-underlying-data



文章来源: symfony2 - adding choices from database