2014-03-29 22 views
6

因此,進入故障排除第5天仍然無法解決問題。我甚至爲了解決這個問題而創建了一個特殊的表單,但仍然無法取得任何進展。基本問題:我有一個通過FormBuilderInterface使用表單修飾符構建的Symfony2表單,用於根據用戶選擇表單中第一個實體動態填充一個字段。表單中還有3個集合(表示與表單主要類的一對一關聯)。Symfony2「此表單不應包含額外字段」錯誤與收集和動態字段

無論我做什麼,在if ($form->isValid())我得到了太熟悉和有趣的「錯誤:此表單不應包含額外的字段。」表單提交錯誤(3次,每次收集1次)。

值得注意的可能與修復相關:如果我從窗體中刪除收集實體,它會正確驗證。對於表單中的任何集合,或3個集合中的2個(我試過所有)的任意組合,它會拋出「此表單不應包含額外字段」的錯誤。

下面是表單類型代碼:

class ThisDataClassType extends AbstractType 
{ 

protected $user_id; 

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

/** 
* @param FormBuilderInterface $builder 
* @param array $options 
*/ 
public function buildForm(FormBuilderInterface $builder, array $options) 
{ 

    $user_id = $this->user_id; 

    $builder->add('firstChoice', 'entity', array(
      'class' => 'MyBundle:FirstChoice', 
      'query_builder' => function(firstChoiceRepository $repository) use ($user_id) { 
        return $repository->createQueryBuilder('f') 
         ->where('f.user = ?1') 
         ->andWhere('f.isActive = 1') 
         ->setParameter(1, $user_id); 
       }, 
      'property' => 'firstChoice_name', 
      'required' => true, 
      'mapped' => false, 
      'label' => 'block.firstChoice.name' 
     )) 
     ->add('sub_block_name','text', array(
      'label' => 'subblock.block.name', 
      'max_length' => 50, 
      'required' => true, 
      'attr' => array(
       'placeholder' => 'subblock.phv.name', 
       'pattern' => 'alpha_numeric' 
      ) 
     )) 

     // ... bunch of other standard form types (text, etc.) ... // 

     ->add('subdata1', 'collection', array(
      'type' => new SubData1Type() 
     )) 
     ->add('subdata2', 'collection', array(
      'type' => new SubData2Type() 
     )) 
     ->add('subdata3', 'collection', array(
      'type' => new SubData3Type() 
     )); 

    $formModifier = function(FormInterface $form, $firstChoice_id) { 

     $form->add('secondChoice', 'entity', array(
      'class'   => 'MyBundle:SecondChoice', 
      'query_builder' => function(secondChoiceRepository $S_repository) use ($firstChoice_id) { 
      return $S_repository->createQueryBuilder('s') 
       ->where('s.firstChoice_id = ?1') 
       ->andWhere('s.isActive = 1') 
       ->setParameter(1, $firstChoice_id); 
      }, 
      'property' => 'secondChoice_name', 
      'label'  => 'block.secondChoice.name' 
     )); 
    }; 

    $builder->addEventListener(
     FormEvents::PRE_SET_DATA, 
     function(FormEvent $event) use ($formModifier) { 
      $data = $event->getData()->getId(); 
      $formModifier($event->getForm(), $data); 
     } 
    ); 

    $builder->get('firstChoice')->addEventListener(
     FormEvents::POST_SUBMIT, 
     function(FormEvent $event) use ($formModifier) { 
      $data = $event->getForm()->getData(); 
      $formModifier($event->getForm()->getParent(), $data->getId()); 
     } 
    ); 

    $builder->setMethod('POST'); 
} 

/** 
* @param OptionsResolverInterface $resolver 
*/ 
public function setDefaultOptions(OptionsResolverInterface $resolver) 
{ 
    $resolver->setDefaults(array(
     'data_class' => 'MyBundle\Entity\ThisDataClass', 
     'user_id' => null, 
     'translation_domain' => 'block', 
     'cascade_validation' => true 
    )); 
} 

/** 
* @return string 
*/ 
public function getName() 
{ 
    return 'ThisDataForm'; 
} 
} 

...和基本控制器(僅用於測試的那一刻):

public function TestFormAction(Request $request, $whichSize) 
{ 
    $user_id = $this->getUser()->getId(); 
    $success = 'Not submitted'; 

    $dataclass = new Entity\ThisDataClass(); 
    $subdata1 = new Entity\SubData1(); 
    $subdata2 = new Entity\SubData2(); 
    $subdata3 = new Entity\SubData3(); 

    if (!$request->isMethod('POST')) { 
     $dataclass->getSubData1()->add($subdata1); 
     $dataclass->getSubData2()->add($subdata2); 
     $dataclass->getSubData3()->add($subdata3); 
    } 

    $form = $this->createForm(new Form\ThisDataClassType($user_id), $dataclass, array(
     'action' => $this->generateUrl('my_custom_test_route', array('whichSize' => $whichSize)), 
     'user_id' => $user_id 
    )); 

    $form->handleRequest($request); 

    if ($form->isValid()) { 
     $success = 'Success!!'; 
     return $this->render('MyBundle:DataClassTestForm.html.twig', array('dataClassTestForm' => $form->createView(), 'whichSize' => $whichSize, 'success' => $success)); 

    } else { 
     $success = $form->getErrorsAsString(); 
    } 

     return $this->render('MyBundle:DataClassTestForm.html.twig', array('dataClassTestForm' => $form->createView(), 'whichSize' => $whichSize, 'success' => $success)); 

} 

要提一對夫婦的其他重要點:

  • 表格顯示正確(所有實體顯示正確的值並根據需要更新)
  • 所有預期的POST變量是在後的數據(通過檢查螢火蟲和Symfony的的探查)
  • 還有那些沒有映射到 類(除了具有'mapped' => false的firstChoice場在後數據沒有額外的變量集, 的CSRF _token,但我得到的錯誤是否我明確啓用CSRF _token 與否,並再次錯誤消失時,我刪除集合)

不勝感激任何人的見識什麼是我我錯過了。

回答

8

經過一天半的休息和走開之後,當我坐下時,答案突然出現,而且很明顯。寫入的控制器僅在第一次創建時(即未發生提交/ POST事件時)將子數據類添加到表單中。因此,在提交事件之後創建的表單具有所有的發佈數據,但這些類不與其關聯。該控制器目前已被改寫如下現在確認出現預期的形式:

public function TestFormAction(Request $request, $whichSize) 
{ 
    $user_id = $this->getUser()->getId(); 
    $success = 'Not submitted'; 

    $dataclass = new Entity\ThisDataClass(); 
    $subdata1 = new Entity\SubData1(); 
    $subdata2 = new Entity\SubData2(); 
    $subdata3 = new Entity\SubData3(); 
    $dataclass->getSubData1()->add($subdata1); 
    $dataclass->getSubData2()->add($subdata2); 
    $dataclass->getSubData3()->add($subdata3); 

    $form = $this->createForm(new Form\ThisDataClassType($user_id), $dataclass, array(
     'action' => $this->generateUrl('my_custom_test_route', array('whichSize' => $whichSize)), 
     'user_id' => $user_id 
    )); 

    $form->handleRequest($request); 

    if ($form->isValid()) { 
     $success = 'Success!!'; 
    } else { 
     $success = 'Invalid!!'; 
    } 

} // RESULT::Success!! 
+0

如果你想設置他們只有一次(例如,使用不同的控制器動作時),你可以設置'allow_add'到TRUE;,所以你的物品被添加到集合中作爲「規範客戶」會這樣做,但這意味着表單中的字段可以被操縱 – Tim

相關問題