6

私のSymfony2プロジェクトでは、データベース内の既存のテーブルのリストを作成する必要があります。プロジェクトですべてのテーブルがエンティティとして使用されているわけではなく、リスト自体はエンティティではなく単純な配列である必要があるため、このためのsqlステートメントを作成しました。このsqlステートメントは、カスタムサービスの関数に埋め込まれています(徹底的にテストされています)。

ここで、フォームタイプで、上記の関数の結果配列をフィールドに入力します。これらは、ユーザーが選択できるオプションになります。

私の質問は、フォームタイプでサービスにアクセスするにはどうすればよいですか?

4

4 に答える 4

16

単純なソリューションがあります。これは純粋なOOPであり、フレームワーク固有の構成はありません。コンストラクターを使用して、サービスインスタンスをフォームタイプインスタンスに手動で挿入するだけです。

class SomeType extends AbstractType
{
    private $provider;

    public function __construct(DataBaseTableNameProvider $provider)
    {
        $this->provider = $provider;
    }

    public function buildForm(FormBuilder $builder, array $options)
    {
         $builder->add('tables', 'choices', array(
             'choices' => $this->provider->getTableNames(),
         ));
    }
}

次に、例としてコントローラーで次のようにします。

public function newAction()
{
     $form = $this->createForm(new SomeType($this->get('table_name_provider'));

     // more stuff
}

フレームワーク構成を使用して、 http://symfony.com/doc/2.0/cookbook/form/create_custom_field_type.html#creating-your-field-type-as-a-serviceに従って、まったく同じことを行うことができます。

唯一の違いは、DICを使用して型をインスタンス化し、正しい依存関係を注入することに注意を払うことです。次に、コントローラーを変更する必要があります。

public function newAction()
{
     $form = $this->createForm('some_type_alias');

     // more stuff
}
于 2013-01-24T10:16:00.080 に答える
7

フォームタイプの翻訳サービスアクセスの例:

フォームタイプクラス:

class TaskType extends AbstractType {
    ....
    public function setDefaultOptions(OptionsResolverInterface $resolver) {
        $resolver->setDefaults(array(
            't' => 'Symfony\Bundle\FrameworkBundle\Translation\Translator',
        ));
    }  

    public function buildForm(FormBuilderInterface $builder, array $options) {
        $t = $options['t'];
        $t->trans('string to translate');
        ....
    }

コントローラ:

public function someAction() { 
    $form = $this->createForm(new TaskType(), 
                                $task, 
                                array('t' => $this->get('translator')));
于 2013-10-21T18:57:12.670 に答える
3

symfonyのベストプラクティス

フォームタイプをサービスとして登録することもできます。これは、フォームタイプでコンテナによる依存関係の注入が必要な場合にのみ必要です。それ以外の場合は、オーバーヘッドが不要であるため、すべてのフォームタイプクラスに対してこれを行うことはお勧めしません。

# src/AppBundle/Resources/config/services.yml
services:
    app.form.type.gender:
        class: AppBundle\Form\Type\ SomeType
        arguments:
            - "@app.table_name_provider"
        tags:
            - { name: form.type }
$form = $this->createForm(SomeType::class)
于 2016-08-26T16:27:09.137 に答える
1

Symfony 3.Xのアップデート、2つのオプションがあります...

オプションを介してサービスを送信する

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setRequired('option_key');
}

次に、それをコントローラーに通します

$form = $this->createForm(XXXType::class, $entity, array(
    'option_key' => $this->get('service_you_want_to_call')
));

フォームをサービスとして定義する

このオプションはよりクリーンなIMOであり、フォームを呼び出すすべての場所にオプションを送信する必要はありません

class XXXType extends AbstractType
{
    private $service;

    public function __construct(ServiceType $service)
    {
        $this->service = $service;
    }

次に、構成でサービスを定義します

services:
    app.form.type.XXX:
        class: AppBundle\Form\XXXType
        arguments: ['@service_you_want_to_call']
        tags:
            - { name: form.type }

でフォームを呼び出すたびに

$this->createForm(XXXType::class, $data, $options)

symfonyはそのサービス引数を使用する必要があることを知るのに十分賢いので(form.typeタグのためにそれを知っています)、コンストラクターにデータを渡す必要はもうありません。

Symfonyドキュメント:フォーム内からサービスまたは設定にアクセスする方法

于 2017-04-21T10:54:29.780 に答える