我经常使用ChoiceType类型的Symfony表单字段,对应于Entity-object-fields,其中Choice Assert定义了它的有效选择。像这个例子:
在实体类中:
/**
* @var string
*
* @ORM\Column(name="myField", type="string", length=10, nullable=false)
* @Assert\NotNull()
* @Assert\Choice(choices={"Choice A", "Choice B", "Choice C"})
*/
private $myField;
并在表格中:
$builder->add('myField', ChoiceType::class, array(
'choices' => array(
'Choice A' => 'Choice A',
'Choice B' => 'Choice B',
'Choice C' => 'Choice C',
),
'expanded' => true,
'multiple' => false,
))
这些选择会不时地改变,我必须在实体类和所有引用它的表单类中同步该更改。
问题是:表单是否有办法接管已在实体类中定义的选择?或者只存储一次选择的另一种方式?
我按照my comment on Hakims answer中提到的那样实现了它:
class MyEntity
{
const VALID_VALUES_AS_FORM_CHOICES = true;
const VALID_VALUES_AS_HASH = true;
const VALID_VALUES_AS_LIST = false;
const VALID_EXAMPLE_PROPERTY_VALUES = [
'entities.MyEntity.exampleProperty.values.what' => 'what',
'entities.MyEntity.exampleProperty.values.ever' => 'ever',
];
/**
* @var string
* @ORM\Column(name="example_property", type="string", length=10, nullable=true, options={"default" : "what"})
* @Assert\Choice(callback = "getValidExamplePropertyValues", message = "{{ value }} is not a valid value.")
*/
private $exampleProperty;
/**
* Gets a list (default for use within Assert\Choice(callback="getValidExamplePropertyValues")
* or a hash (for use in a ChoiceType form field)
* of the valid values for the type property
*
* @param bool $asFormChoices optional set to self::VALID_VALUES_AS_FORM_CHOICES to get a hash with values also as keys, defaults to self::VALID_VALUES_AS_LIST
* @return array
*/
public static function getValidExamplePropertyValues($asFormChoices = self::VALID_VALUES_AS_LIST)
{
return $asFormChoices ? self::VALID_EXAMPLE_PROPERTY_VALUES : array_values(self::VALID_EXAMPLE_PROPERTY_VALUES);
}
// other code
}
在表单构建器中:
$builder->add('exampleProperty', \Symfony\Component\Form\Extension\Core\Type\ChoiceType::class, [
'choices' => MyEntity::getValidExamplePropertyValues(MyEntity::VALID_VALUES_AS_FORM_CHOICES),
]);
答案 0 :(得分:1)
你可以试试这个:
创建外部类来处理您的选择。
答案 1 :(得分:0)
我通常创建一个Type类,我存储我的选择数组。例如,名为myFieldType的类。我存储带有类型的受保护数组,以及整个数组或一个元素的getter。
class myFieldType
{
protected $myField = [
'Choice A' => 'Choice A',
'Choice B' => 'Choice B',
'Choice C' => 'Choice C',
]
public function getType()
{
return $this->myField
}
您还可以创建其他获取者,例如标签或其他任何内容。
答案 2 :(得分:0)
自己提供一个可能的解决方案:可以从验证服务中读取元数据,例如:在控制器中:
foreach($this->get('validator')
->getMetadataFor(myClass::class)
->getPropertyMetadata('myField')[0]->constraints as $constraint) {
if (is_a($constraint, Choice::class)) {
dump($constraint->choices);
break;
}
}
Etvoilà,我们在实体的验证 - 注释中定义了一系列选择。这可以抽象为在表单定义中使用,但这对我来说有点间接。我的问题更多的是“有没有一种预期的方法来同步实体类和它的形式之间的选择?”