4

我有一个布尔字段,我已将其作为选择字段(是或否)放入表单中。如果没有数据转换器,我会得到 0 或 1。我添加了一个视图 BooleanToStringTransformer (这似乎是合理的):

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

当我尝试显示表单时,我收到错误“Expected a Boolean.”。不过,在创建表单之前,我的字段设置为 false。

我试图将其设置为模型转换器:表单已显示,但当我提交时,我的字段被声明为无效。

我究竟做错了什么?

编辑:我现在几乎明白了。

  • 我使用模型转换器而不是视图转换器(选择字段适用于字符串或整数,而不是布尔值)
  • 我将选择列表从更改array(true => 'Yes', false => 'No')array('yes' => 'Yes', 'no' => 'No')

所以代码现在看起来像->addModelTransformer(new BooleanToStringTransformer('yes'))

数据转换有效,除了我的字段始终设置为 true,无论我选择什么值。

怎么了?

4

3 回答 3

5

答案是:我不应该认为默认的 Symfony BooleanToStringDataTransformer 正在完成这项工作。它为 false 值而不是字符串返回 null。

所以我创建了自己的数据转换器:

<?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;
    }
}
于 2013-08-30T09:32:49.200 回答
1

您似乎使用了 View 转换器而不是 Model 转换器。如果基础模型需要布尔值,您需要在模型转换器中将 0/1 反向转换为布尔值。

.. 或者您可能错过了在视图转换器中实现反向转换方法。

在此处阅读更多关于 View 和 Model 转换器的区别。

于 2013-08-30T09:00:26.333 回答
0

另一种解决方法可以是:

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

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

        $event->setData($data);
    }
})
于 2015-02-25T11:14:12.597 回答