2017-03-21 2 views
0

런타임시 yml 양식을 생성합니다. yml 파일의 요소를 살펴보고 해당 필드를 양식에 추가합니다. 루트 폼은 다음과 같이 생성됩니다.Symfony2 : 공장 빌더를 사용하여 작성된 양식을 다른 양식의 콜렉션 유형 필드에 추가하는 방법은 무엇입니까?

$form = $factory->createBuilder("form", $this->userData); 

yml에는 컬렉션 필드도 정의 할 수있는 옵션이 있습니다. 컬렉션 필드 유형 string, Symfony\Component\Form\ResolvedFormTypeInterface이어야 공급 될 type 옵션, Symfony\Component\Form\FormTypeInterface

하지만 런타임에뿐만 아니라 포함 된 양식을 구축하고 있기 때문에, 나는 늘 유형을 가지고도 여기에 FormTypeInterface

이 필요 내가 $options['template']가 포함 된 양식에 대한 유형이 YML 파일에 정의되어 어떻게 여기

$options = isset($config["options"]) ? $config["options"]: []; 
if ($config['type'] == 'collection') { 
    $options['type'] = $this->buildForm($options['template'], $factory); 
    unset($options['template']); 
    $form->add($config["name"], $config["type"], $options); 
} 

을해야 할 일의 샘플 코드입니다. 그래서 폼은 런타임에 빌드됩니다. 어떻게 그것을 루트 폼에 포함합니까?

편집 : 사실 필드가 하나 인 경우 컬렉션 필드에 email라고 말하면 정상적으로 작동합니다. 그러나 yml spec을 사용하면 사용자가 컬렉션 필드에서 여러 필드를 정의 할 수 있습니다. symfony에서 이것은 포함 된 양식 유형을 정의하고 컬렉션 유형의 type 옵션을 해당 양식 유형으로 설정하여 수행 할 수 있습니다. 하지만 런타임에 양식을 만들 때 어떻게해야합니까?

+0

전략 패턴을 구현합니다. yml에 정의 된 각 유형에 대해 특정 양식 유형을 루트 양식에 추가하는 특정 클래스를 구현합니다. 이러한 클래스는 하나의 메소드 (예 : 'addType()'. 또한 루트 형식을 생성자 인수로 받아들이므로 형식을 추가 할 수 있습니다. 그런 다음 동일한 방식으로 컬렉션 유형을 확장합니다. –

+0

이러한 yml 파일은 수천 가지가 될 것이며 런타임에 렌더링해야 할 것입니다. Theres 수천의 클래스를 만들 옵션이 없습니다 .. 또한 PHP는 런타임에 인터페이스를 기반으로 클래스를 정의 할 수 없습니다! – Broncha

+0

아이디어 만 있으면 도움이 될 것입니다. 폼 타입 (필드)마다 하나의 클래스를 의미합니다. 제한된 양식 유형 집합이 있습니다 (예 : 텍스트, 선택, 텍스트 영역, .. 각각의 클래스. 그런 다음 루트 양식 클래스는 이벤트 구독자를 사용하여 pre_set_data 이벤트에 대해 제공된 데이터를 기반으로 해당 필드를 추가 할 수 있습니다. 귀하의 경우 yml에서 오는 문자열 집합입니다. 지금까지 멀지 않았다면 Symfony의 동적 양식을 확인하십시오 : http://symfony.com/doc/2.8/form/dynamic_form_modification.html –

답변

0

런타임에 양식을 작성하는 양식 유형 클래스를 정의하여 해결했습니다. 구성 (양식 디자인)은 생성자로 전달되고 buildForm은 디자인에 따라 각 필드를 추가합니다.

class RuntimeFormType extends AbstractType 
{ 
    /** 
    * @var string 
    */ 
    private $name; 

    /** 
    * @var array 
    */ 
    private $config; 

    /** 
    * RuntimeFormType constructor. 
    * @param string $name 
    * @param array $config 
    */ 
    public function __construct($name, array $config) 
    { 
     $this->name = $name; 
     $this->config = $config; 
    } 

    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     foreach($this->config as $config){ 
      $options = isset($config["options"]) ? $config["options"]: []; 

      if($config['type'] == 'image'){ 
       $options['data_class'] = null; 
       $options['multiple'] = false; 

       $options['attr'] = [ 
        "accept" => "images/*" 
       ]; 

       $builder->add($config["name"], "file", $options); 
      }else{ 
       $builder->add($config["name"], $config["type"], $options); 
      } 
     } 
    } 


    public function getName() 
    { 
     return $this->name; 
    } 
} 

및 빌더에서

, 유형이 collection 유형이 양식 유형을 초기화하고 루트 양식에 추가 할 수 있습니다.

if ($config['type'] == 'collection') { 
    $template = $options['template']; 

    unset($options['template']); 
    $options['type'] = new RuntimeFormType($config["name"], $template); 

    $form->add($themeConfig["name"], $themeConfig["type"], $options); 
}