2013-08-30 29 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); 
    } 
})