如何将一个类变量映射到Symfony中的两个表单字段

时间:2017-05-12 06:35:46

标签: php forms symfony

我希望使用Symfony 2.8来创建数据类的表单,例如Symfony docs中使用的Task

我的Task类使用整数字段flags来存储集合不同的bool值。例如,is completed的值存储为第一位,is urgent存储为第二位:

  • 任务已完成且紧急 - > flags = 0
  • 任务已完成且紧急 - > flags = 1
  • 任务已完成且紧急 - > flags = 2
  • 任务已完成且紧急 - > flags = 3
  • ...

问题:如何将此单个字段字段映射到两个不同的表单字段并返回?

$builder
    // map first bit to checkbox
    ->add('is_complete', CheckboxType::class, array(
            ...
        )
    )
    // map second bit to selection box "normal"/"urgent"
    ->add('is_urgend', ChoiceType::class, array(
            ...
        )
    )
    ...

解决此问题的正确解决方案是什么?这可以由数据转换器处理吗?据我所知,变换器可以将一个字段转换为另一个类型的字段,但不能将一个字段转换为两个字段。这是对的吗?

我到目前为止找到的唯一解决方案是创建一个包装类TaskWrapper,它不使用标志,但为每个标志值提供不同的bool字段。可以将此类传递给表单而不是原始的Task类。提交表单后,可以将返回的包装器对象手动转换回Task对象。

这可行,但它不是一个干净的解决方案。这是要走的路还是使用Symfony工具有更好的解决方案?

1 个答案:

答案 0 :(得分:1)

我会选择多个布尔属性。在表单级别和持久性级别上更容易。

如果您需要使用该$flags属性并且使用的是Doctrine,则可以使用多个布尔属性而不映射它们。提交表单时,字段将直接映射到实体属性,但mapped = false除外:http://symfony.com/doc/current/reference/forms/types/form.html#mapped

然后为在创建/更新任务之前设置prePersist属性的事件preUpdateflags实现eventlistener:

为了保持一致性,您可以将$urgent$complete属性值设置为setFlags(),因为它只会手动调用或在加载实体时调用。