2012-03-15 24 views
19

Tôi đang cố gắng để truy cập vào thực thể cho một hình thức nhúng được đưa ra trong phụ huynh CollectionType bên FormBuilder:dạng Symfony - Truy cập Entity bên trong Loại mục nhập con trong một CollectionType

ParentType

Class ParentType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder->add('children', CollectionType::class, array(
      'entry_type' => ChildType::class 
     ); 
    } 
} 

ChildType

class ChildType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $child = $builder->getData(); // this returns null 
    } 

    public function getDefaultOptions(array $options) 
    { 
     return array(
      'data_class' => 'Vendor\Bundle\Entity\Child', 
     ); 
    } 
} 

Trong khi tác phẩm này s trong một hình thức bình thường, $child đang được trả về là null. Làm cách nào để truy cập vào thực thể Child bên trong ChildType?

Trả lời

38

Câu trả lời nằm trong việc sử dụng Trình nghe sự kiện để nghe sự kiện PRE_SET_DATA.

Nó sẽ vượt qua đóng của bạn một lớp FormEvent chứa cả biểu mẫu và dữ liệu bị ràng buộc với nó.

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $builder->addEventListener(FormEvents::PRE_SET_DATA, 
     function (FormEvent $event) use ($builder) 
     { 
      $form = $event->getForm(); 
      $child = $event->getData(); 

      if ($child instanceof Child) { 

       // Do what ever you like with $child entity data 

      } 
     } 
    ); 
} 
+1

Để yêu cầu qu rõ ràng estion, bạn có chắc chắn có bất kỳ Bars nào trong thực thể cha của bạn được sử dụng cho dữ liệu của biểu mẫu không? Bạn có thể kiểm tra bằng cách var_dumping bộ sưu tập thanh của bạn từ dữ liệu trong kiểu biểu mẫu gốc của bạn không? – user1207727

+0

Tuyệt vời, cảm ơn! Điều này làm việc hoàn hảo, và cũng dẫn tôi đến một phần trong các tài liệu tôi bỏ qua: [Làm thế nào để tạo động các hình thức sử dụng các sự kiện mẫu] (http://symfony.com/doc/current/cookbook/form/dynamic_form_generation.html) – Nick

+0

Ah , bạn nhận được bình luận của tôi trước khi tôi xóa nó - tôi lười biếng loại trừ một phần của câu trả lời của bạn với formfactory, cố gắng tiếp tục chỉ với người xây dựng chính nó. Sau đó tôi quyết định sử dụng nguyên văn giải pháp của bạn và nó đã hoạt động. Xin lỗi để gây nhầm lẫn! – Nick

2

Đây là giải pháp chi tiết hơn dựa trên user1207727.

Loại Chánh

class FrontentStatsInputFormType extends AbstractType 
{ 

    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->add('records', CollectionType::class, array(
       'entry_type' => FrontendStatsRecordType::class, 
       'allow_add' => false, 
       'allow_delete' => false, 
       'label' => null, 
      )) 
     ; 
    } 

    public function configureOptions(OptionsResolver $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => null 
     )); 
    } 
} 

Loại Child

class FrontendStatsRecordType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder->addEventListener(FormEvents::PRE_SET_DATA, 
      function (FormEvent $event) use ($builder) 
      { 
       $form = $event->getForm(); 
       $child = $event->getData(); 

       if ($child instanceof StatsRecord) { 

        // Do what ever you like with $child entity data 
        // $child->getSomeValue(); 

        $form->add('value', TextType::class); 
       } 
      } 
     ); 

    } 

    public function configureOptions(OptionsResolver $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => 'AppBundle\Entity\StatsRecord', 
     )); 
    } 

} 

Tạo hình thức trong điều khiển

public function indexAction(Request $request, InputForm $inputForm) { 

    $data = array(); 

    foreach ($inputForm->getStatsTemplates() as $template) { 
     $statsRecord = new StatsRecord(); 
     $data['records'][] = $statsRecord; 
    } 


    $form = $this->createForm('AppBundle\Form\FrontentStatsInputFormType', $data); 
    $form->handleRequest($request); 


    if ($form->isSubmitted() && $form->isValid()) { 

     $em = $this->getDoctrine()->getManager(); 

     // Get entries and persist them in the database 
     $records = $form->get('records')->getData(); 
     foreach ($records as $record) { 
      $em->persist($record); 
     } 

     $em->flush(); 

     return $this->redirectToRoute('frontend_index'); 
    } 

    return $this->render('frontend/showInputForm.html.twig', array(
     'inputForm' => $inputForm, 
     'form' => $form->createView(), 
    )); 
} 
Các vấn đề liên quan