我正在开发一个在数据库中存储树的应用程序。应用程序是使用cakephp2.x和jstree3.2.1构建的
保存数据的模式如下: id
-自动递增id,对于树的每个节点都是唯一的 parent_id
-元素的父id; null
如果没有父元素(顶级元素)。 lft
, rght
-使用cakephp的树行为,它使用修改的前序树遍历。这些代表 lft
以及 rght
价值观。 name
-节点的文本名称 pos
-从0开始的整数,用于确定节点在其父节点下的位置。
我遇到的问题是“调整”所有的 pos
更新树中节点的位置时的元素。
例如,考虑以下数据:
id | parent_id | name | pos
--------------------------------------------------
149 | NULL | Foo | 0
150 | 149 | A | 0
151 | 149 | B | 1
152 | 149 | C | 2
153 | 149 | D | 3
154 | 149 | E | 4
155 | 149 | F | 5
从视觉上看,如下所示:
福
一
b
c
d
e
f
现在如果我拖放“e”,那么它在“b”和“c”之间。。。
福
一
b
e(移动)
c
d
f
... 我需要更新 pos
在我的数据库中的值,对于“foo”的子对象。
当发生拖放时,jstree为我提供了:
这个 id
我所移动的元素。”“e”应该是 154
.
这个 parent_id
那个“e”已经放在下面了。在这种情况下 149
因为它仍然是“foo”的子元素,但理论上可以移动到树上的任何其他元素下。
这个 pos
(位置)它被投进去了。这些值从0开始,因此在上面的示例中,移动“e”后,它将进入 pos = 2
.
理解节点可以向上或向下任意方向拖动是很重要的,但是jstree只提供 pos
相对于它在父节点下的位置(以及 parent_id
以及 id
).
所以我可以用新的 pos
对于“e”:
>UPDATE tree SET pos = 2 WHERE id = 154 AND parent_id = 149;
id | parent_id | name | pos
--------------------------------------------------
149 | NULL | Foo | 0
150 | 149 | A | 0
151 | 149 | B | 1
152 | 149 | C | 2
153 | 149 | D | 3
154 | 149 | E | 2 (*updated*)
155 | 149 | F | 5
我的问题是如何重新安排另一个 pos
价值观。例如,“c”现在应该有一个 pos
的价值 4
.
github上有一些代码展示了移动节点时如何保存数据的示例,但我无法理解(尽管我花了好几天的时间)或将其改编为cakephp。实际上,提供的大部分代码都是不必要的,因为cake负责生成 lft
以及 rght
价值观。所以我想知道的是如何使用php/mysql将数字“移位”或“调整”回数字序列。
我提供这个以防有帮助:
这个 pos
值按顺序在每个父节点下(父节点id)。因此,如果我们有另一个父元素“bar”,它有子元素“xx”、“yy”和“zz”,则数据可能如下所示。请注意 pos
值是。
所以查询应该只调整 pos
对于给定的 parent_id
在任何特定的时间。在前面的示例中,我只想重新排序 pos
为了 parent_id = 149
-假设我正在移动节点“e”。
id | parent_id | name | pos
--------------------------------------------------
149 | NULL | Foo | 0
150 | 149 | A | 0
151 | 149 | B | 1
152 | 149 | C | 2
153 | 149 | D | 3
154 | 149 | E | 4
155 | 149 | F | 5
906 | NULL | Bar | 0
907 | 906 | XX | 0
908 | 906 | YY | 1
909 | 906 | ZZ | 2
2条答案
按热度按时间dzjeubhm1#
weltschmerz的回答似乎很有效。
不过,我会使用一个存储过程,将它们全部重新编号,并在将项“拖放”到新位置后调用它。比如:
那你就把它叫做。。。
holgip5t2#
您有足够的信息来修改同级节点的位置。
如果154已移动到位置2:
我们要“删除”节点,然后再“插入”它。大致如下:
通常,在父节点之间移动节点时: