2013-08-30 32 views
4

我有一個布爾型字段,我把它作爲選擇字段放入(是或否)。 我會得到0或1沒有數據轉換器。 我添加了一個視圖BooleanToStringTransformer(這似乎合理的):Symfony2形式BooleanToStringTransformer問題

$builder 
     ->add(
      $builder->create('myBooleanField', 'choice', array(
       'choices' => array(true => 'Yes', false => 'No'), 
      )) 
      ->addViewTransformer(new BooleanToStringTransformer('1')) 
     ) 

,當我嘗試顯示窗體,我得到的錯誤「需要一個布爾值。」。 雖然在創建表單之前我的字段設置爲false。

我試圖將它設置爲模型轉換器:表單顯示,但是當我提交它時,我的字段被聲明爲無效。

我在做什麼錯?

編輯:我現在差不多了。

  • 我使用的模型變壓器,而不是一個視圖變壓器(選擇現場工作人員用繩子或整數,而不是布爾值)
  • 我改變了我的選擇名單從array(true => 'Yes', false => 'No')array('yes' => 'Yes', 'no' => 'No')

因此,代碼現在看起來像->addModelTransformer(new BooleanToStringTransformer('yes'))

除了我的字段總是設置爲true,無論我選擇什麼值,數據轉換的工作原理都是如此。

怎麼了?

回答

5

答案是:我不應該想到默認的Symfony BooleanToStringDataTransformer正在完成這項工作。它返回的是空值而不是字符串。

所以我創建了自己datatransformer:

<?php 

use Symfony\Component\Form\DataTransformerInterface; 
use Symfony\Component\Form\Exception\TransformationFailedException; 

class BooleanToStringTransformer implements DataTransformerInterface 
{ 
    private $trueValue; 
    private $falseValue; 

    public function __construct($trueValue, $falseValue) 
    { 
     $this->trueValue = $trueValue; 
     $this->falseValue = $falseValue; 
    } 

    public function transform($value) 
    { 
     if (null === $value) { 
      return null; 
     } 

     if (!is_bool($value)) { 
      throw new TransformationFailedException('Expected a Boolean.'); 
     } 

     return true === $value ? $this->trueValue : $this->falseValue; 
    } 

    public function reverseTransform($value) 
    { 
     if (null === $value) { 
      return null; 
     } 

     if (!is_string($value)) { 
      throw new TransformationFailedException('Expected a string.'); 
     } 

     return $this->trueValue === $value; 
    } 
} 
1

您似乎已經使用了View變壓器而不是Model變壓器。如果底層模型需要布爾值,則需要在模型轉換器中將0/1反向轉換爲布爾值。

..或者您可能錯過了在您的視圖轉換器中實現逆向轉換方法。

瞭解更多關於View和Model變形金剛here之間的區別。

+0

不能布爾值作爲標準化的數據?順便說一句,BooleanToStringTransformer是Symfony窗​​體核心擴展的一部分,我沒有實現它。 – Nanocom

0

另一個解決方法可以是:

->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) { 
    $data = $event->getData(); 

    if (isset($data['myBooleanField'])) { 
     $data['myBooleanField'] = (bool) $data['myBooleanField']; 

     $event->setData($data); 
    } 
})