1 回答
TA贡献1825条经验 获得超6个赞
!!!我强烈建议您不要在那里做什么!
原因:
您的表单类型的数据类设置为实体(据我所知)。并且表单旨在修改给定的对象(您的实体)。现在,如果您过滤该表单类型的字段,然后表单尝试设置“新”值,Pointage
则可能会删除所有不在表单提交中的对象(特别是所有被过滤掉的对象)。如果表单调用,您将丢失数据- 我不太确定,是否总是调用它,即使/设置为 false。如果你忘记了,这会让你的生活变得悲惨。我相信这总是被称为标准。setPointages
allow_add
allow_remove
CollectionType
阅读一些代码后更新:关于调用setPointages
:如果addPointage
/removePointage
存在,它们将被调用。但是,PropertyAccessor
(属性访问组件)从目标对象(!)读取先前的值,并且将计算差异并相应地调用 add/remove -> 删除不在新集合中的任何实体
可能的解决方法
大量使用数据映射器/数据转换器/表单事件以某种方式隐藏存在更多
Pointage
实体的事实。这可能工作得很好,但它使事情复杂化了很多,但仍然可能成为一个干净的解决方案。总体思路是:
但是,您可能必须花费大量时间了解表单组件的内部结构才能正确安全地执行此操作……(一个指针
MergeCollectionListener
是看一下ResizeFormListener
,它根据给定的数据添加和删除子表单。请记住,如果您过滤数据,您可能应该创建自己的集合类型并添加一个新的表单侦听器来优雅地处理所有内容)表单渲染:从实体获取(事务,所有积分)->您的转换器/映射器/表单事件处理程序(事务,所有->过滤积分)->表单(事务,过滤积分)
表单提交:表单(事务,过滤点)->您的转换器/映射器/表单事件处理程序(事务,过滤->“新所有”点)->设置实体(事务,所有点)
代替这种整合入
AffaireType
,添加另一种形式类型AffairePointageType
具有两个字段:affaire
(AffaireType
无pointages
)和pointages
(CollectionType
),并调用它像
$filteredPointages = someFilterFunction($affaire->getPointages());
$this->createForm(AffairePointageType::class, [
'affaire' => $affaire,
'pointages' => $filteredPointages,
], [
'pointages' => ... //the option you provide for the CollectionType
]);
显然,您可以提供任何积分,由您喜欢的任何过滤器过滤,并且只会编辑您提供的那些,而保留与其他任何相关联的内容
$affaire
不变。但是请注意,您必须自己处理添加或删除的积分。(这可能会破坏关注点分离)本质上,这是以前解决方法的一个更易于理解的版本,其中所有过滤器逻辑都是外部的,但是由于表单没有传达“您可以编辑事务的积分”,而是“您可以同时编辑事务和一组可能相关或不相关的点数”,它在语义上很清楚,并且不会让未来的用户(包括您在内)感到惊讶。
但是,我相信您的方法可能存在缺陷……但是由于不清楚您实际要达到的目标,因此很难提出适当的解决方案。
如果只是“显示的(子)表单太多” - 那么它更多的是显示问题,可以并且可能应该通过 javascript 或 css ( display:none
) 或两者来修复。(这是恕我直言更好的方法,不会与表单逻辑和/机制混淆)。
- 1 回答
- 0 关注
- 134 浏览
添加回答
举报