2016-08-31 4 views
1

私はhttp://symfony.com/doc/2.8/form/data_transformers.htmlデータトランスフォーマー/ W Symfony2のカスタムフォームタイプ - サービスインジェクション

class ClientType extends AbstractType 
{ 
    private $manager; 

    public function __construct(ObjectManager $manager) 
    { 
     $this->manager = $manager; 
    } 

    /** 
    * @param FormBuilderInterface $builder 
    * @param array $options 
    */ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->add('shortname') 
      ->add('shortinfo') 
      ->add('web')     
      ->add('user', CollectionType::class, array(
       'entry_type'  => IntegerType::class, 
       'allow_add'  => true, 
       'allow_delete' => true 
      )); 

     $builder->get('user')->addModelTransformer(new UserToPrimaryKeyTransformer($this->manager)); 
    } 
} 

に応じて多対多の関係を満たすために、データのトランスでカスタムフォームの種類を実装していたサブタイプUserTypeされます:

class UserType extends AbstractType 
{ 
    /** 
    * @param FormBuilderInterface $builder 
    * @param array $options 
    */ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->add('loginname') 
      ->add('firstname') 
      ->add('lastname') 
      /* ... */ 
      ->add('email') 
      ->add('id') 
     ; 
    } 
} 

トランスクラスはかなりのドキュメントからコピー&ペーストである:

class UserToPrimaryKeyTransformer implements DataTransformerInterface 
{ 

    private $manager; 

    public function __construct(ObjectManager $manager) 
    { 
     $this->manager = $manager; 
    } 

    /** 
    * Transform entity to pkid 
    * 
    * @param User 
    * @return integer 
    */ 
    public function transform($user) 
    { 
     if(null === $user) { 
      return -1; 
     } 

     return $user->getId(); 
    } 

    /** 
    * @param integer $pkid 
    */ 
    public function reverseTransform($pkid) 
    { 
     if (!$pkid) { 
      return; 
     } 

     $user = $this->manager 
      ->getRepository('AcmeBundle:User') 
      // query for the user with this id 
      ->find($pkid) 
     ; 

     if (null === $user) { 
      /* ... */ 
     } 

     return $user; 
    } 

} 

それほど文脈のために。問題は、しかし、教義エンティティマネージャの正確注入、サービス定義にあるようだ:私はこのフォームを投稿するとき

acme.form.type.client: 
    class: AcmeBundle\Form\ClientType 
    arguments: [ @doctrine.orm.entity_manager ] 
    tags: 
     - { name: form.type } 

は今、私が手:何で Type error: Argument 1 passed to AcmeBundle\Form\ClientType::__construct() must implement interface Doctrine\Common\Persistence\ObjectManager, none given

任意のアイデアやポインタをやっている? @doctrine.orm.entity_manager変数はどこかでインスタンス化する必要がありますか?私はsymfonyの2.8によ

は、ところで

+0

サービス定義の入力ミスがありますか? 'AcmeBundle \ Form \ CrmClientType'の代わりに' AcmeBundle \ Form \ ClientType'と言っているので – DonCallisto

+0

いいえ、申し訳ありません...どちらの場合でも 'AcmeBundle \ Form \ ClientType'にする必要があります。簡略化して忘れました。 –

答えて

-1

あなたのフォームタイプは、ObjectManagerのを期待して、あなたは、EntityManagerを注入しています。私はEntityManagerにコンストラクタパラメータを変更することを提案し、それは動作します

+1

いいえ、 (EntityManagerInterfaceを介して) 'ObjectManager'を実装しています – DonCallisto

+0

これは正しい@DonCallistoであり、[docs](http://www.doctrine- project.net/api/orm/2.3/class-Doctrine.ORM.EntityManager.html)(EntityManagerInterfaceを介して)少し見つけにくいです –

0

問題が見つかりました。それが働いた

$form = $this->get('form.factory')->createNamed('', new \AcmeBundle\Form\ClientType($em), $client); 

にこれを変更した後

// create a form with an empty name in order to avoid needing a JSON ROOT element 
$form = $this->get('form.factory')->createNamed('', new \AcmeBundle\Form\ClientType(), $client); 

:私は手動APIの要件を(それは私が開発していRESTサービスの)履行するために、フォームをインスタンス化されたことを忘れてしまいました。

ありがとうございました!

+0

なぜあなたは手動で依存関係を扱っていますか?あなたのフォームタイプは登録されているので、コンテナ – kamwoz

+0

からそれを得ることができます。上記のコメントに記載されているように、それ以外の場合に必要となるJSONルート要素を削除するには、空の名前のフォームを作成する必要があります。あなたがより良い解決策を持っていれば、私は喜んでいるでしょう! –

+0

申し訳ありませんが、私はこれにつながるので、質問を見つけることができません。 –

関連する問題