3

コミューン、地域、国をそれぞれドロップダウンリストで選択するためのフォームタイプ(そして、別のフォームに埋め込まれている)を意図したクラスがあります(地域は国によって異なります)。国リストを作成するときに、特定の国がデフォルトで選択されるようにします。これは私が持っているものです:

$factory = $builder->getFormFactory();
$builder->add('pais', 'entity', array(
'class' => 'Codesin\ColegiosBundle\Localidad\Pais',
'property' => 'nombre',
'query_builder' => function (EntityRepository $repositorio) {
    $qb = $repositorio->createQueryBuilder('pais')
        ->orderBy('pais.nombre');
        return $qb;
    }
));

私は使用してみましpreferred_valueた(クラス内でデータベースにアクセスできないため、どこからでも取得できないオブジェクトが必要であると書かれています)およびdata(機能しません)。どちらの場合もエンティティの ID を使用してみました。この場合、選択したデフォルト値を設定するにはどうすればよいですか?

4

4 に答える 4

4

よし、ようやくサービスとしての作り方がわかった気がする。「なぜそれをサービスにするのですか?」と聞かれるかもしれません。これは、エンティティ マネージャーを挿入する必要があるためです。次のチュートリアルがお役に立てば幸いです。

カスタム フォーム タイプの Preferred_choices

データベースにいくつかの国が保存されていて、それらがCountryエンティティであり、Doctrine で適切に定義されているとします。しかし、問題があります。世界中には 250 近くの国があり、ユーザーは 1 つの国の出身である可能性が最も高いのです。たとえば、国をデフォルトで選択するか、リストの一番上に置く必要があるとします。

ステップ 1: フィールドに入力する

カスタム フォーム タイプを作成しているとしますCountryType。定義しましょう。

class CountryType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('country', 'entity', array(
             'class' => 'Acme\AcmeBundle\Locality\Country',
             'property' => 'name',
             'query_builder' => function (EntityRepository $repository) {
                 $qb = $repository->createQueryBuilder('country')->orderBy('country.name');
                 return $qb;
             }
        ));
    }

    public function getDefaultOptions(array $options)
    {
        return array('data_class' => 'Acme\AcmeBundle\Locality\Country');
    }

    public function getName()
    {
        return 'countrytype';
    }

}

そして、どこかから呼び出すと、

$builder->add('country', new CountryType());

デフォルトで選択された国を取得しないことを除いて、すべてうまく機能します。さらに悪いことに、追加しようとすると

'preferred_choices' => array(15) //Say, 15 is the id of the country

あなたのオプションに、例外が発生します。そして、いくつかの奇妙な理由で、これを行う:

$defaultCountry = new Country();
$defaultCountry->setId(15);

その後

'preferred_choices' => array($defaultCountry)

どちらも機能しません。

ここから楽しみが始まります。

ステップ 2: EntityManager を追加する

必要なエンティティを検索するには、データベースにクエリを実行する必要があります。そして今は Doctrine がないのでアクセスできませんEntityManager。クラスに 1 つ追加し、コンストラクターに引数として渡し、クラスのプライベート プロパティとして格納します。

class CountryType extends AbstractType
{
    //Add this
    public function __construct(EntityManager $em)
    {
        $this->em = $em;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('country', 'entity', array(
             'class' => 'Acme\AcmeBundle\Locality\Country',
             'property' => 'name',
             'query_builder' => function (EntityRepository $repository) {
                 $qb = $repository->createQueryBuilder('country')->orderBy('country.name');
                 return $qb;
             }
        ));
    }

    public function getDefaultOptions(array $options)
    {
        return array('data_class' => 'Acme\AcmeBundle\Locality\Country');
    }

    public function getName()
    {
        return 'countrytype';
    }

    //Add this
    private $em;
}

その後、データベースにクエリを実行します。

class CountryType extends AbstractType
{
    public function __construct(EntityManager $em)
    {
        $this->em = $em;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        //Add the following lines
        $qb = $this->em->createQueryBuilder();
        $resultset = $qb->select('country')
                        ->from('Acme\AcmeBundle\Locality\Country', 'country')
                        ->where('country.id = ?1')
                        ->setParameter(1, 15)
                        ->getQuery()
                        ->execute();

        $default = $resultset[0];

        $builder->add('country', 'entity', array(
             'class' => 'Acme\AcmeBundle\Locality\Country',
             'property' => 'name',
             'preferred_choices' => array($default), //Add this too
             'query_builder' => function (EntityRepository $repository) {
                 $qb = $repository->createQueryBuilder('country')->orderBy('country.name');
                 return $qb;
             }
        ));
    }

    public function getDefaultOptions(array $options)
    {
        return array('data_class' => 'Acme\AcmeBundle\Locality\Country');
    }

    public function getName()
    {
        return 'countrytype';
    }

    private $em;
}

しかし、ここで問題が発生しました。もう呼び出すことはできません!! EntityManager特にこれをコントローラーから呼び出すのではなく、埋め込む場合はどうすればよいでしょうか? ここで魔法がかけられます。

ステップ 3: サービスにする

なんで?このようにして an を注入できるEntityManagerからです。次の行に移動しAcme/AcmeBundle/Resources/cofig/services.ymlて追加します。

acme.acmebundle.countrytype:
    class: Acme\AcmeBundle\Types\CountryType
    arguments: ["@doctrine.orm.entity_manager"]
    tags:
        - { name: form.type, alias: countrytype }

ここにいくつかのメモ:

  • サービスに渡される引数は別のサービス、つまり DoctrineEntityManagerです。この引数は関数のコンストラクターに渡され、別の場所から注入されます。このようにして、常にEntityManager.
  • タグには、指定された両方のタグが含まれていることを確認してください。aliasタグは、getName()カスタム タイプ (この場合はcountrytype.

依存性注入とサービスについて詳しく知りたい場合は、ここにアクセスしてください:サービス コンテナー。

さて、大きな問題です。それをどのように呼ぶのでしょうか?

ステップ 4: サービスを呼び出す

やり方は非常に簡単です。この行を覚えていますか?

$builder->add('country', new CountryType());

ここで、次のように変更します。

$builder->add('country', 'countrytype');

それでおしまい!これで、カスタム タイプにエンティティ マネージャーがアタッチされ、引数を渡す必要がなくなりました。次のプロジェクトで頑張ってください!

于 2013-09-06T07:49:49.153 に答える
0

モデル オブジェクトでフォーム タイプを使用している場合は、オブジェクト自体にデフォルトを設定します。

于 2013-09-05T08:08:29.573 に答える
0

SET_DATAまたはPOST_SET_DATAフォーム イベントで試してください: ラムダ関数内で次のようなことができます。

$data = $event->getData();
$form = $event->getForm();

// search in the form for the right entity to set as country.. let's consider $country

$data->setCountry($country);
$event->setData($data);

それはうまくいくかもしれません。試してみて、進捗状況をお知らせください

于 2013-09-05T08:30:30.993 に答える