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+ 用に更新 (および改善)

まず、ルート オブジェクトの一部として国を渡す必要はありません。ただし、国が DB に格納される場合を除きます。

利用可能な国を DB に保存する場合は、イベント リスナーを使用できます。そうでない場合 (またはリスナーを使用したくない場合) は、オプション領域に国を追加できます。

オプションの使用

コントローラーで..

$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 に答える