2016-03-11 38 views
1

形勢Symfony的表單驗證設置無效子形式有效,使用學說ORM驗證約束時

我有我渲染與標籤前端子的形式,所以只有一個子窗體的窗體類型(如標籤)可以一次顯示。因此,當發生不同標籤上的錯誤時,我彈出一個顯示錯誤的對話框。通過遞歸循環最終的請求處理表單對象。

驗證約束條件寫入表單類型。這會產生一個最終表單對象,我可以循環,並且子表單被指示爲valid = false當真的發生錯誤時。

目標

我希望外包所有驗證約束到實體的ORM映射。

問題

在i外包所有驗證錯誤入ORM映射,最後形成對象包含子形式的都有效=真即使強硬其內表單部件與驗證錯誤提交。只有最上面的表單級別有效= false。

這種現象發生在建立所有沒有 - 的子表單時,以及事件訂閱者。

我希望子窗體也被設置爲無效的最終形式的對象,當在那裏發生錯誤,我怎麼能實現這一目標?

  • 的Symfony 2.8.3
  • 學說ORM 2.5.4

編輯

使用error_bubbling我沒有工作。也許我沒有正確使用它?

利用該輸入:

form 
{{ dump(form) }} 

form.vars.valid 
{{ dump(form.vars.valid) }} 

form.vars.errors 
{{ dump(form.vars.errors) }} 

form.children.sections.vars.errors 
{{ dump(form.children.sections.vars.errors) }} 

form.children.sections.vars.valid 
{{ dump(form.children.sections.vars.valid) }} 

form.children.sections.children.general.vars.errors 
{{ dump(form.children.sections.children.general.vars.errors) }} 

form.children.sections.children.general.vars.valid 
{{ dump(form.children.sections.children.general.vars.valid) }} 

form.children.sections.children.general.children.lang.vars.valid 
{{ dump(form.children.sections.children.general.children.lang.vars.valid) }} 

form.children.sections.children.general.children.lang.vars.errors 
{{ dump(form.children.sections.children.general.children.lang.vars.errors) }} 

我收到這個輸出:

form 
FormView {#12833 ▼ 
    +vars: array:28 [▶] 
    +parent: null 
    +children: array:3 [▶] 
    -rendered: false} 

form.vars.valid 
false 

form.vars.errors 
FormErrorIterator {#12832 ▼ 
    -form: Form {#5652 ▶} 
    -errors: array:1 [▶] 
} 

form.children.sections.vars.errors 
FormErrorIterator {#12837 ▼ 
    -form: Form {#5649 ▶} 
    -errors: [] 
} 

form.children.sections.vars.valid 
true 

form.children.sections.children.general.vars.errors 
FormErrorIterator {#12841 ▼ 
    -form: Form {#5498 ▶} 
    -errors: [] 
} 

form.children.sections.children.general.vars.valid 
true 

form.children.sections.children.general.children.lang.vars.valid 
true 

form.children.sections.children.general.children.lang.vars.errors 
FormErrorIterator {#12851 ▼ 
    -form: Form {#2009 ▶} 
    -errors: [] 
} 

我生成該錯誤在form.children.sections.children.general.children.lang。我想從這個位置,遞歸父母有...有效=假

我試過error_bubbling = true在以下情況下,具有相同的轉儲結果。

  • 所有表單類型與小部件本身
  • 所有形式的類型,而小部件本身
  • 只有部件

我怎麼錯了,還是我需要另一種解決方法?

EDIT 2

所以現在我試圖error_bubbling =假在下列情況下,與仍然相同轉儲結果。

  • 所有表單類型與小部件本身
  • 所有形式的類型,而小部件本身
  • 只有部件

這裏是一些片段

實體

/** 
* @ORM\Entity(repositoryClass="Myvendor\CoreBundle\Entity\MyItemRepository") 
* @ORM\Table(name="myitem") 
*/ 
class MyItem 
{ 
    /** 
    * @ORM\Column(type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    protected $id; 

    /** 
    * @var \Myvendor\CoreBundle\Entity\Language 
    * 
    * @Assert\Type("Myvendor\CoreBundle\Entity\Languag") 
    * @ORM\ManyToOne(targetEntity="Myvendor\CoreBundle\Entity\Language") 
    * @ORM\JoinColumn(name="language_id", nullable=true, referencedColumnName="langid") 
    */ 
    private $lang; 

/** 
* Set lang 
* 
* @param \Myvendor\CoreBundle\Entity\Language $lang 
* 
* @return MyItem 
*/ 
public function setLang(\Myvendor\CoreBundle\Entity\Language $lang = null) 
{ 
    $this->lang = $lang; 

    return $this; 
} 

/** 
* Get lang 
* 
* @return \Myvendor\CoreBundle\Entity\Language 
*/ 
public function getLang() 
{ 
    return $this->lang; 
} 
/** 
* Get id 
* 
* @return integer 
*/ 
public function getId() 
{ 
    return $this->id; 
} 



} 

初步形成類型

class MyItemType extends AbstractMyvendorType 
{ 

    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $sections = $builder->create('sections', 'form', array(
      'mapped' => false, 
      'label' => false, 
      'attr' => array(
       'data-sections' => '1' 
      ), 
      'error_bubbling' => false 
     )); 
     $builder->add($sections); 
     $builder->addEventSubscriber(new DynamicSubforms()); 
    } 

    public function configureOptions(OptionsResolver $resolver) 
    { 
     parent::configureOptions($resolver); 
     $resolver->setDefaults(array(
      'error_bubbling' => false 
     )); 
    } 
} 

事件訂閱

class DynamicSubforms implements EventSubscriberInterface 
{ 

    public static function getSubscribedEvents() 
    { 
     return array(
      FormEvents::PRE_SET_DATA => 'onPreSetData' 
     ); 
    } 

    /** 
    * Adding subtypes, depending on the myitem type. 
    * 
    * @author FPI 
    * @param FormEvent $event    
    */ 
    public function onPreSetData(FormEvent $event) 
    { 
     /** 
     * 
     * @var $data \Myvendor\CoreBundle\Entity\MyItem 
     * @var $form \Symfony\Component\Form\Form 
     */ 
     $data = $event->getData(); 
     $steptype = $data->getType(); 
     $form = $event->getForm(); 
     $options = $form->getConfig()->getOptions(); 
     $sections = $form->get('sections'); 

     $default_section_options = array(
      'mapped' => false, 
      'data' => $data 
     ); 
     // Every steptype has section "general" 
     $sections->add('general', GeneralType::class, array_merge($default_section_options, array(
      'label' => 'general', 
      'error_bubbling' => false 
     ))); 

    } 
} 

子表單類型

class GeneralType extends AbstractType 
{ 

    protected $em; 

    protected $choiceOption; 

    public function __construct(EntityManager $em, ChoiceOption $choice_option) 
    { 
     $this->em = $em; 
     $this->choiceOption = $choice_option; 
    } 

    /* 
    * Here are set the static options for each widget. 
    * The dynamic options on specific widgets are specified in the event subscriber. 
    * {@inheritdoc} 
    * 
    * @author FPI 
    */ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 

     /* Language */ 
     $builder->add('lang', 'entity', array(
      'label' => 'language', 
      'class' => 'MyvendorCoreBundle:Language', 
       'error_bubbling' => false 
     )); 

    } 

    public function configureOptions(OptionsResolver $resolver) 
    { 
     $resolver->setDefaults(array(
      'error_bubbling' => false 
     )); 
    } 
} 
+0

嘗試http://symfony.com/doc/current/reference/forms/types/text.html#error-bubbling – Manolo

+0

我已經使用過了,但是我無法實現我的目標。我編輯了我的帖子。也許我做錯了什麼? –

+0

你是什麼意思*這種現象發生時,建立所有子窗體沒有 - * – Manolo

回答

0

如果你不想傳遞錯誤到表單父項,您應該設置error_bubbling se,因爲error_bubbling默認爲false ,除非形式爲複合error_bubbling)。

+0

幫助@FabianPicone? – Manolo

+0

設置** error_bubbling **爲** false **沒有幫助,請參閱我的**編輯2 **以上 –

+0

好吧,如果將'mapped'設置爲'false',我認爲錯誤不會被捕獲。 – Manolo