2017-02-23 7 views
1

질문을 공식화하는 방법을 모르겠으므로 자유롭게 편집하십시오.ZF2 Doctrine - 특정 ID가 필요한 의존성 주입을 처리하는 방법

현재 상황은 다음과 같습니다. 폼 클래스를 인스턴스화하는 팩토리 클래스가 있습니다. DI (Dependency Injection)는 생성자 주입을 통해 수행됩니다. 내 문제는이 양식 요소에 findby 메서드가 필요한 Doctrine ObjectMultiCheckbox가 있다는 것입니다. 이 findby 메서드는 특정 엔터티의 ID가 필요하지만 폼에 팩토리 클래스를 통해 ID를 전달할 수는 없습니다.

내 질문은 어떻게 처리 할 수 ​​있습니까? 가장 좋은 방법은 무엇입니까?

class CustomerFormFactory implements FactoryInterface 
{ 
    /** 
    * Create service 
    * 
    * @param ServiceLocatorInterface $serviceLocator 
    * @return Form 
    */ 
    public function createService(ServiceLocatorInterface $serviceLocator) 
    { 
     $em = $serviceLocator->get('Doctrine\ORM\EntityManager'); 
     return new CustomerForm($em); 
    } 
} 

그리고이 같은 서비스 로케이터를 통해 양식을 얻을 :

은의이 내 팩토리 클래스라고하자

$customerForm = $this->getServiceLocator()->get('CustomerForm'); 

가 어떻게 서비스 로케이터에 ID를 전달할 수 있습니다 ? 그리고 양식 요소에 특정 ID가 필요한 경우 DI 및 서비스의 목적을 깨뜨리지 않습니까? 나는이 같은 자신에 의해 "고전적인"방법을 가서 폼 요소를 인스턴스화해야 :

$customerForm = new CustomerForm(EntityManager $em, int $id); 

정말 내가 무엇을해야하는지 모르겠어요 또는 무엇이 처리하는 가장 좋은 방법입니다.

답변

3

양식에 옵션을 삽입하려면 CreationOptions 팩토리 클래스를 사용할 수 있습니다.

FormElementManager (양식 요소의 serviceLocator)에 대한 구성을 설정하여 시작하십시오. 당신의 Module.php

:

use Zend\ModuleManager\Feature\FormElementProviderInterface; 

class Module implements FormElementProviderInterface 
{ 
    // your module code 

    public function getFormElementConfig() 
    { 
     return [ 
      'factories' => [ 
       'myForm' => \Module\Form\MyFormFactory::class 
      ] 
     ]; 
    } 
} 

우리는 우리가 종속의를 포함하여 양식을 반환 우리의 공장을 만들어야합니다 configruation을 설정 한 후. 또한 폼 클래스 내에서 재사용 할 수있는 옵션을 삽입합니다.

use Zend\ServiceManager\FactoryInterface; 
use Zend\ServiceManager\MutableCreationOptionsTrait; 
use Zend\ServiceManager\ServiceLocatorInterface; 

class MyFormFactory implements FactoryInterface 
{ 
    use MutableCreationOptionsTrait; 

    /** 
    * Create service 
    * 
    * @param ServiceLocatorInterface $serviceLocator 
    * 
    * @return mixed 
    */ 
    public function createService(ServiceLocatorInterface $serviceLocator) 
    { 
     return new MyForm(
      $serviceLocator->getServiceLocator()->get('Doctrine\ORM\EntityManager'), 
      'MyForm', 
      $this->getCreationOptions() 
     ); 
    } 
} 

대신이 같은 \Zend\ServiceManager\FactoryInterface\Zend\ServiceManager\Factory\FactoryInterface을 사용하는 것이 좋습니다 ZF3를 사용 ZF3이 공장을 이용하여가는 방법입니다. 위의 예에서는 ZF2 (v2.7.6 zendframework/zend-servicemanager) 버전을 사용했습니다. ZF3 버전으로 바꾸려면 클래스 Zend\ServiceManager\FactoryInterface::class에 대한 설명을 참조하십시오. 우리가 FormElementManager 클래스에 ::get('myForm', ['id' => $id])를 호출 할 때

그래서 지금 당신은 우리가 함께 통과 한 옵션이 포함됩니다 MyForm 인스턴스와 형태의 옵션을 얻을 것이다.

그래서 양식은 비슷한 보일 수 있습니다 :

class MyForm extends \Zend\Form\Form 
{ 
    public function __construct(
     \Doctrine\Common\Persistence\ObjectManager $entityManager, 
     $name = 'myForm', 
     $options = [] 
    ) { 
     parent::__construct($name, $options); 

     $this->setEntityManager($entityManager); 
    } 

    public function init() { 
     /** add form elements **/ 
     $id = $this->getOption('id'); 
    } 
} 

또한 양식을 작성하고 EntityManager를 설정할 수 있습니다,하지만 모두 당신에게 달려 있습니다. 생성자 삽입을 사용할 필요가 없습니다.

그래서 컨트롤러에 대한 exmaple :

$myForm = $this->getServiceManager()->get('FormElementManager')->get('myForm', ['id' => 1337]); 
$options = $myForm->getOptions(); 
// your options: ['id' => 1337] 

당신은 당신의 컨트롤러 내에서 ServiceManager에 또는 로케이터가 없을 수 있습니다 당신이 FormElementManager을 주입있어 있도록 ZF2.5 + 또는 ZF3을 사용 또는 Form 클래스를 팩토리별로 컨트롤러에 추가합니다.

양식 내에 다른 종속성이 없지만 옵션을 설정하려는 경우 각 클래스에 대한 팩터 리를 만들 필요가 없습니다. InvokableFactory::class을 다시 사용할 수 있습니다. 그러면 creationOptions도 삽입됩니다.

+1

대단한 답변입니다. 고맙습니다 :) – Sepultura