2014-11-07 1 views
2

종속 선택 상자를 만들려고합니다. 첫 번째 선택 상자가 선택되면 두 번째 선택 상자를 채워야합니다.양식 이벤트에서 매핑되지 않은 양식 데이터에 액세스

첫 번째 선택 상자가 모델에 매핑되지 않았습니다. 내 컨트롤러에서 수동으로 값을 $form->get('emailTemplateBlockType')->setData($emailTemplateBlockType)으로 설정합니다. 내 양식 이벤트에서이 데이터를 사용하여 두 번째 선택 상자를 만들려면 어떻게해야합니까?

$builder 
     ->add('emailTemplateBlockType', 'entity', array(
      'class' => 'MbDbMVibesBundle:EmailTemplateBlockType', 
      'property' => 'name', 
      'mapped' => false, 
      'empty_value' => 'Choose a block type', 
      'attr' => array(
       'class' => 'emailTemplateBlockTypeSelect', 
      ) 
     )) 
     ->add('save', 'submit'); 


    $builder->addEventListener(FormEvents::POST_SET_DATA, function (FormEvent $event) { 
     $form = $event->getForm(); 
     $data = $event->getData(); 

      echo "name: ".$form->get('emailTemplateBlockType')->getData()->getName(); 
      die; 
    }); 

첫 번째 선택 상자를 내 frontcontroller에 다시 게시하는 jQuery와 함께 onChange 이벤트가 있습니다. 프론트 컨트롤러는 폼을 다시 생성하지만 이번에는 첫 번째 선택 상자의 값이 추가됩니다. 하지만 제출이 아니므로 POST_SUBMIT 이벤트를 사용하면 문제가 해결되지 않습니다. 내 컨트롤러에서

발췌문 :

$form = $this->createForm(new EmailTemplateSiteEmailTemplateBlockType(), $entity, array(
     'action' => $this->generateUrl('_email_tpl_site_block_edit', array(
      'emailTemplateSiteId' => $emailTemplateSiteId, 
      'emailTemplateSiteBlockId' => $emailTemplateSiteBlockId, 
     )) 
    )); 

    if ($request->request->get('blockTypeId')) { 
     $this->get('logger')->debug('setting block type'); 

     $emailTemplateBlockType = $em->getRepository('MbDbMVibesBundle:EmailTemplateBlockType') 
      ->find($request->request->get('blockTypeId')); 

     if ($emailTemplateBlockType) 
      $form->get('emailTemplateBlockType')->setData($emailTemplateBlockType); 
     else 
      throw new $this->createNotFoundException('Cannot find blocktype with id '.$request->request->get('blockTypeId')); 

    } 

    $form->handleRequest($request); 
+0

대신 해당 이벤트를 'POST_SUBMIT'에 바인딩 했습니까? –

+0

예, 방금 시도했는데 양식을 다시로드하기 위해 제출하지 않았기 때문에 작동하지 않습니다. 아마 제 질문을 수정해야합니다. – rolandow

+1

@rolandow : PRE_SUBMIT 이벤트를 사용하면 원시 데이터를 얻습니다. – jamek

답변

2

나는 마침내 그것을 못을 박았다 생각합니다. 여기에 내 함정을 설명해 드리겠습니다.이 기사의 내용은 결국 구현 방법에 대한 전체 기사를 참조하십시오. Forms in Symfony2: dependent selectboxes

우선 양식 양식 PRE_SUBMIT을 트리거하려면 전체 양식을 제출해야합니다. 양식에 하나의 변수 만 게시 할 수는 없습니다.

둘째, PRE_SUBMIT 이벤트에서 데이터가 배열 대신 객체에 저장되는 것을 완전히 놓쳤습니다. 실제로는 this post에 완전히 언급되었습니다. 그래서 사용해야 :

$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) use ($addEmailTemplateBlock) { 
    $form = $event->getForm(); 
    $data = $event->getData(); 

    if (array_key_exists('emailTemplateBlockType', $data)) { 
     $addEmailTemplateBlock($form, $data['emailTemplateBlockType']); 
    } 
}); 

셋째는 내 매핑되지 않은 폼 요소가 PRE_SET_DATA에 액세스 할 수 없다는 것입니다,하지만 POST_SET_DATA에서와 있습니다.

넷째, 이미 첫 번째와 두 번째를 선택했다면 첫 번째 선택 상자를 변경할 때 문제가 있다는 것입니다. 첫 번째 선택 상자가 변경되면 두 번째 선택 상자의 값이 실제로 유효하지 않기 때문에 이는 의미가 있습니다. 이 문제를 해결하는 가장 쉬운 방법은 첫 번째 선택 상자의 변경 이벤트에서 값을 비어있게 설정하는 것입니다.

종속 필드를 추가 할 때 컨트롤러 나 자바 스크립트에 추가 스크립트가 필요하지 않음을 지적하고자합니다. 이것에 대한 모든 논리는 폼 빌더 내에서 이루어 지므로 Airam의 접근 방식보다 재사용이 가능한 코드를 생성한다고 생각합니다.