我可以从实体的选择断言中获取symfony2 ChoiceType中的选项吗?

时间:2016-02-15 09:30:43

标签: symfony doctrine-orm

我经常使用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),
]);

3 个答案:

答案 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à,我们在实体的验证 - 注释中定义了一系列选择。这可以抽象为在表单定义中使用,但这对我来说有点间接。我的问题更多的是“有没有一种预期的方法来同步实体类和它的形式之间的选择?”