2017-04-26 31 views
1

我使用EntityType创建表单,但未映射到实体上。表单很长,用户多次重复使用相同的选项,然后当他对表单有效时,如果有效,我会将$form->getData()存储在会话中。非映射表单,实体类型和数据属性

当我生成表单时,我注入了$data。它非常适用所有选项,除了EntityType,我不明白为什么...

$data,我已经在EntityType选择的对象的ArrayCollection,但形式不选择它。我用mapped = false,因为如果我删除它,我已经一个错误:

Entities passed to the choice field must be managed. Maybe persist them in the entity manager?

有人我有一个想法,怎么办?

回答

4

设置mapped = false不应该是这种情况下的解决方案,因为您需要将存储的数据写入此字段中,对不对?所以mapped = false避免它(见更多关于mapped选项here

这里的问题是,EntityType需要从每个项目得到id值,并要求这些项目EntityManager实际管理:

Entities passed to the choice field must be managed. Maybe persist them in the entity manager?

实体处于MANAGED状态,其持久性由EntityManager管理。换句话说,如果一个实体从数据库中提取或者通过EntityManager#persist注册为新的实体,它将被管理。

在你的情况下,这些实体来自会话,所以你有两个选择:

  • 重新查询从数据库中存储的实体:

    if (isset($data['foo']) && $data['foo'] instanceof Collection) { 
        $data['foo'] = $this->getDoctrine()->getRepository(Foo::class)->findBy([ 
         'id' => $data['foo']->toArray(), 
        ]); 
    } 
    
  • 或者设置自定义choice_value选项以避开默认值:

    $form->add('foo', EntityType::class, [ 
        'class' => Foo::class, 
        'choice_value' => 'id', // <--- default IdReader::getIdValue() 
    ]); 
    
+1

非常感谢,我尝试了第二种方法,因为使用更方便。它的工作原理,并感谢解释。 – mpiot

相关问题