ArrayCollection(表单集合)索引冲突在 Symfony 2 中

2022-08-30 22:24:39

我正在使用Symfony2来建立我的页面。当我尝试更新表单集合时(如说明书条目“如何嵌入表单集合”中所述),我得到了前端索引和后端ArrayCollection索引的冲突。

我有关系用户<>地址(OneToMany)。用户想要创建/更新/删除他的地址,因此他可以在javascript部分新地址元素的帮助下在前端添加/删除。他执行以下操作:

(1) 添加新地址 (索引: 0)

(2)添加新地址(索引:1)并立即再次删除此地址

(3) 添加新地址 (索引: 2).

当他单击保存按钮时,以下代码保存/更新用户(及其地址):

 $this->em->persist($user);
 $this->em->flush();

例如,新地址将正确保存到数据库中。现在,用户想要更新地址,例如索引为0。当他现在单击保存按钮时,它会使用“索引0”更新地址,但同时,它会再次将具有“索引2”的地址添加到数据库(对象)中。为了更好地理解这个问题,我画了一幅小插图(手工制作,对不起我的艺术技巧不好):

Collection error image现在,我的对象/数据库中有两倍于“索引1”的地址。我知道为什么会发生这种情况,这是因为第一个“索引1”地址映射到ArrayCollection元素“数字1”,第二个地址映射到“数字2”(因为前端名称“索引2”)。你可以说:“它只是填满地址,直到它到达后端的前端索引”。但是我该如何解决此行为?

站点说明:此行为发生在使用ajax请求时,因为如果您在单击“保存按钮”后重新加载页面,它将使用后端中的索引正确重新索引前端中的地址。

我对处理这种情况的建议:

单击“使用服务器端索引保存”后,对前端索引重新编制索引。这是一个明确/唯一的解决方案吗?


答案 1

是的,这是Symfony表单收集的问题,恕我直言,它没有简单的解决方案。但是我不得不问,你为什么不做与页面刷新完全相同的事情?您只能使用集合刷新 html 代码段。代码段的 HTML 代码可以来自服务器端。回到你的问题 - 是的,重新索引是很好的解决方案,直到你不想尝试自己编写自定义集合类型。

symfony/symfony/issues/7828

在集合中验证也存在类似的问题 - symfony/symfony/issues/7468

好吧,我认为默认集合类型和Symfony文档中的教程有一些缺点。希望这有帮助。


答案 2

我通过修改Symfony文档中给出的Javascript / Jquery代码在客户端解决了这个问题。

我不是通过计算子元素来对新元素进行编号,而是查看最后一个元素的id并使用正则表达式提取其索引。

添加元素时,我将最后一个索引递增 1。这样,我永远不会使用相同的索引。

这是我的代码:

// Initializing default index at 0
var index = 0;

// Looking for collection fields in the form
var $findinput = $container.find(':input');

// If fields found then looking for last existing index
if ( $findinput.length > 0 ) {

    // Reading id of last field
    var myString = $findinput.last().attr('id')

    // Setting regular expression to extract number from id containing letters, hyphens and underscores
    var myRegex = /^[-_A-Za-z]+([0-9]+)[-_A-Za-z]*$/

    // Executing regular expression on last collection field id
    var test = myRegex.exec(myString);

    // Extracting last index and incrementing by 1
    if (test.length > 0) index = parseInt(test[1]) + 1;
}