Symfony2表单阻止更改实体的字段

时间:2016-11-25 09:34:18

标签: php forms symfony entity

我正在寻找一种将实体绑定到表单的方法,但是我需要映射(显示)它的特定字段,但不能由提交表单的用户修改。

到目前为止我检查了什么:

  1. 使用已停用的属性 - 未提交,实体的字段设为null
  2. 使用HTML readonly属性 - 仍可通过操作HTML
  3. 进行修改
  4. 使用read_only字段选项 - 与上面相同
  5. 我的字段是一个复选框,但我更喜欢这种字段的通用解决方案,因为我将来会有更多字段。

    我还想避免额外的查询。

    有什么想法吗?

3 个答案:

答案 0 :(得分:1)

第一&第三种解决方案并不好。

我刚才有同样的问题。这就是我解决它的方法:

我使用了第二个解决方案,并且由于您在应用程序中拥有该实体,因此您可以通过操纵HTML来简单地覆盖用户已更改的任何值(这是一个应该处理的风险)。

或者,您可以绘制一个未映射的HTML复选框(带有随机ID和名称),并且它不会映射到您的实体。

答案 1 :(得分:1)

我想我找到了解决这个问题的正确方法。它不是很灵活,但将其转换为扩展应该可以很容易地处理。我刚刚创建的基本版本可以找到here。一点解释:

  1. 将选项mapped设置为false
  2. 的字段
  3. 创建事件处理函数(setUnmappedField)
  4. 将EventListener附加到PRE_SET_DATA和SUBMIT事件。
  5. PRE_SET_DATA确保在最初呈现表单时该字段具有正确的值。 SUBMIT确保即使用户在提交表单之前更改了字段的值,也会将字段的值恢复为初始值。

    对于UI / UX,禁用和只读属性在这里,它也可以在没有这些属性的情况下工作。

    如果您需要,可以随意使用它来构建表单扩展。我可能会建立一个扩展,以便在我需要它之后使其更加灵活。

    @EDIT

    我刚刚意识到这可以更轻松 - 让字段映射! updated这里要点。不需要PRE_SET_DATA监听器和mapped=false

答案 2 :(得分:0)

我建议你做1和2的组合。见下面的样本

 ->add('trainings', 'entity', array(
                'label'=> 'Upcoming training(s)',
                'choice_label' => 'CompleteTitle',
                'multiple' => 'true',
                'expanded' => 'true',
                'by_reference'=>false,
                'class' => 'TrainingBundle:Trainings' ,
                'query_builder' => function (EntityRepository $er) use ($options) {
                    return $er->getTrainingByParentId($options['parent_id']);
                },
            )
        )
        ->add('PastTrainings', 'entity', array(
                'label'=> 'Past trainings',
                'choice_label' => 'CompleteTitle',
                'multiple' => 'true','expanded' => 'false',
                'disabled' => 'true',
                'class' => 'TrainingBundle:Training' ,'mapped'=>false,
                'query_builder' => function (EntityRepository $er) use ($options) {
                    return $er->getTrainingByParentId($options['parent_id']);
                },


            )