布尔值和选择 symfony 类型
Boolean values and choice symfony type
使用 Symfony 框架的选择类型,我们可以决定使用这两个键播放列表、单选按钮或复选框:
'multiple' => false,
'expanded' => true, //example for radio buttons
假设 'choices' 键中作为数组给出的不同选择的值是布尔值,而不是字符串:
$builder->add('myproperty', 'choice', array(
'choices' => array(
'Yes' => true,
'No' => false
),
'label' => 'My Property',
'required' => true,
'empty_value' => false,
'choices_as_values' => true
));
使用列表 (select) 显示不同的选择没有问题,当显示表单时,列表中的正确选择是 selected。
如果我添加我之前谈到的两个键(多个键和扩展键)以用单选按钮替换列表,我的字段没有 selected 按钮(尽管它与 select).
有人知道为什么吗?
如何轻松让它发挥作用?
谢谢
注意:事实上,我认为它不适用于 then 中的任何一个,因为值是布尔值并最终成为字符串,但因为它适用于列表,我想知道为什么它不适用于其他值。
我添加了一个数据转换器;
$builder->add('myproperty', 'choice', array(
'choices' => array(
'Yes' => '1',
'No' => '0'
),
'label' => 'My Property',
'required' => true,
'empty_value' => false,
'choices_as_values' => true
));
$builder->get('myProperty')
->addModelTransformer(new CallbackTransformer(
function ($property) {
return (string) $property;
},
function ($property) {
return (bool) $property;
}
));
这很神奇:现在我选中了正确的单选按钮并在实体中设置了正确的值。
另一个解决方案是使用Doctrine Lifecycle Callbacks and php Type Casting.
使用此 FormType:
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
//...
$builder->add('active', ChoiceType::class, [
'choices' => [
'active' => true,
'inactive' => false
]
])
像这样的实体:
//...
use Doctrine\ORM\Mapping as ORM;
/**
* ...
* @ORM\HasLifecycleCallbacks() /!\ Don't forget this!
* ...
*/
class MyEntity {
//..
/**
* @var bool
*
* @ORM\Column(name="active", type="boolean")
*/
private $active;
//...
/**
* @ORM\PrePersist()
*/
public function prePersist()
{
$this->active = (bool) $this->active; //Force using boolean value of $this->active
}
/**
* @ORM\PreUpdate()
*/
public function preUpdate()
{
$this->active = (bool) $this->active;
}
//...
}
我的解决方案:
/**
* @var BooleanToStringTransformer $transformer
*/
private $transformer;
/**
* @param BooleanToStringTransformer $transformer
*/
public function __construct(BooleanToStringTransformer $transformer) {
$this->transformer = $transformer;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('myProperty', TextType::class, [
'empty_data' => false,
])
;
$builder->get('myProperty')->addModelTransformer($this->transformer);
}
<?php
namespace App\DataTransformer;
use Symfony\Component\Form\DataTransformerInterface;
/**
* Class BooleanToStringTransformer
*
* @package App\DataTransformer
*/
class BooleanToStringTransformer implements DataTransformerInterface
{
/**
* @param bool $boolean
*
* @return string
*/
public function transform($boolean): string
{
// transform the boolean to a string
return $boolean ? 'true' : 'false';
}
/**
* @param string $string
*
* @return bool
*/
public function reverseTransform($string): bool
{
// transform the string back to a boolean
return filter_var($string, FILTER_VALIDATE_BOOL);
}
}
使用 Symfony 框架的选择类型,我们可以决定使用这两个键播放列表、单选按钮或复选框:
'multiple' => false,
'expanded' => true, //example for radio buttons
假设 'choices' 键中作为数组给出的不同选择的值是布尔值,而不是字符串:
$builder->add('myproperty', 'choice', array(
'choices' => array(
'Yes' => true,
'No' => false
),
'label' => 'My Property',
'required' => true,
'empty_value' => false,
'choices_as_values' => true
));
使用列表 (select) 显示不同的选择没有问题,当显示表单时,列表中的正确选择是 selected。
如果我添加我之前谈到的两个键(多个键和扩展键)以用单选按钮替换列表,我的字段没有 selected 按钮(尽管它与 select).
有人知道为什么吗?
如何轻松让它发挥作用?
谢谢
注意:事实上,我认为它不适用于 then 中的任何一个,因为值是布尔值并最终成为字符串,但因为它适用于列表,我想知道为什么它不适用于其他值。
我添加了一个数据转换器;
$builder->add('myproperty', 'choice', array(
'choices' => array(
'Yes' => '1',
'No' => '0'
),
'label' => 'My Property',
'required' => true,
'empty_value' => false,
'choices_as_values' => true
));
$builder->get('myProperty')
->addModelTransformer(new CallbackTransformer(
function ($property) {
return (string) $property;
},
function ($property) {
return (bool) $property;
}
));
这很神奇:现在我选中了正确的单选按钮并在实体中设置了正确的值。
另一个解决方案是使用Doctrine Lifecycle Callbacks and php Type Casting.
使用此 FormType:
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
//...
$builder->add('active', ChoiceType::class, [
'choices' => [
'active' => true,
'inactive' => false
]
])
像这样的实体:
//...
use Doctrine\ORM\Mapping as ORM;
/**
* ...
* @ORM\HasLifecycleCallbacks() /!\ Don't forget this!
* ...
*/
class MyEntity {
//..
/**
* @var bool
*
* @ORM\Column(name="active", type="boolean")
*/
private $active;
//...
/**
* @ORM\PrePersist()
*/
public function prePersist()
{
$this->active = (bool) $this->active; //Force using boolean value of $this->active
}
/**
* @ORM\PreUpdate()
*/
public function preUpdate()
{
$this->active = (bool) $this->active;
}
//...
}
我的解决方案:
/**
* @var BooleanToStringTransformer $transformer
*/
private $transformer;
/**
* @param BooleanToStringTransformer $transformer
*/
public function __construct(BooleanToStringTransformer $transformer) {
$this->transformer = $transformer;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('myProperty', TextType::class, [
'empty_data' => false,
])
;
$builder->get('myProperty')->addModelTransformer($this->transformer);
}
<?php
namespace App\DataTransformer;
use Symfony\Component\Form\DataTransformerInterface;
/**
* Class BooleanToStringTransformer
*
* @package App\DataTransformer
*/
class BooleanToStringTransformer implements DataTransformerInterface
{
/**
* @param bool $boolean
*
* @return string
*/
public function transform($boolean): string
{
// transform the boolean to a string
return $boolean ? 'true' : 'false';
}
/**
* @param string $string
*
* @return bool
*/
public function reverseTransform($string): bool
{
// transform the string back to a boolean
return filter_var($string, FILTER_VALIDATE_BOOL);
}
}