8

我希望用自定义查询中的值填充 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()
      ));

    }
}

选择路线表格

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

3 回答 3

19

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

$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(),
                ))
            ;
        })
    ;
}
于 2013-04-05T15:08:41.243 回答
11

我还不能评论或投反对票,所以我将在这里回复 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-b​​ased-on-the-underlying-data

于 2013-12-06T12:28:45.837 回答
0

我通过在构建器上调用 getData 来让它工作

FormBuilderInterface $builder

// 控制器

$myCountries = $this->myRepository->all(['continent' => 'Africa']);
$form = $this->createForm(CountriesType::class, $myCountries);

//表单类型

use Symfony\Component\Form\Extension\Core\Type\ChoiceType;

public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('pages', ChoiceType::class, [
                'choices' => $builder->getData()
            ])
        ;
    }
于 2021-11-03T14:00:34.380 回答