13

タイトル通り、Symfony2フォームのイベントリスナーはサービスコンテナにアクセスできますか?

これは、イベントリスナーの例です(バインド後のイベント用)。

class CustomerTypeSubscriber implements EventSubscriberInterface
{

    public static function getSubscribedEvents()
    {
        return array(FormEvents::POST_BIND => 'onPostBind');
    }

    public function onPostBind(DataEvent $event)
    {
        // Get the entity (Customer type)
        $data = $event->getData();

        // Get current user
        $user = null;    

        // Remove country if address is not provided
        if(!$data->getAddress()) :
            $data->setCountry(null);
        endif;
    }

}
4

2 に答える 2

29

サービス コンテナにアクセスする必要があるのは何ですか?

依存性注入を使用して、任意のサービスをリスナーに注入できます (リスナーをサービスとして定義しているように)。

次のようなことができるはずです。

    service.listener:
    class: Path\To\Your\Class
    calls:
      - [ setSomeService, [@someService] ]
    tags:
      - { [Whatever your tags are] }

そしてあなたのリスナーで:

private $someService;

public function setSomeService($service) {
    $this->someService = $someService;
}

someService は、挿入するサービスの ID です。

必要に応じて @service_container を使用してサービス コンテナーを注入することもできますが、必要なものだけを注入する方がよいでしょう。

于 2012-05-18T16:13:24.347 に答える
5

フォーム サブスクライバーの動作は、通常のイベント リスナーとは少し異なると思います。

コントローラーで、フォームタイプをインスタンス化しています。つまり、

$form = $this->createForm(new CustomerType(), $customer);

コンテナーはコントローラーで使用できるため、フォーム タイプに直接渡すことができます。つまり、

$form = $this->createForm(new CustomerType($this->container), $customer);

私の場合、セキュリティ コンテキストが必要だったので、私の実装 (似ていますが、元の q とは少し異なります):

私のコントローラーで:

$form = $this->createForm(new CustomerType($this->get('security.context')), $customer));

私のフォームクラスでは:

use Symfony\Component\Security\Core\SecurityContext;
class CustomerType extends AbstractType
{
    protected $securityContext;

    public function __construct(SecurityContext $securityContext)
    {
        $this->securityContext = $securityContext;
    }

    public function buildForm(FormBuilder $builder, array $options)
    {
        // Delegate responsibility for creating a particular field to EventSubscriber
        $subscriber = new CustomerAddSpecialFieldSubscriber($builder->getFormFactory(), $this->securityContext);
        $builder->addEventSubscriber($subscriber);
        $builder->add( ... the rest of my fields ... );
    }

    // other standard Form functions
}

そして私のフォームサブスクライバーで

use Symfony\Component\Security\Core\SecurityContext;
CustomerAddSpecialFieldSubscriber
{
    private $factory;

    protected $securityContext;

    public function __construct(FormFactoryInterface $factory, SecurityContext $securityContext)
    {
        $this->factory = $factory;
        $this->securityContext = $securityContext;
    }

    public static function getSubscribedEvents()
    {
        return array(FormEvents::PRE_SET_DATA => 'preSetData');
    }

    public function preSetData(DataEvent $event)
    {
        if (true === $this->securityContext->isGranted('ROLE_ADMIN')) {
            // etc
        }
    }

}

それが役に立てば幸い。

于 2012-07-02T08:17:19.270 に答える