00:00
接下来我们来编写通过拖拽节点改变节点顺序以及父子关系的功能。首先拖拽的页面效果我们参照element UI,它后边呢,有一个叫可拖拽节点,它是通过设置drag属性让整个EL变成可拖拽的,我们可以参照它的示例代码这一块呢,我们只需要给yellow tree加一个dragable,包括这个dragable属性呢,它默认我们来看一下,在属性这一块有一个叫dragable,它默认的是first,我们把它置为true,我们就开启了拖拽节点的功能,好把它复制过来,那写到我们yellow tree的属性上。接下来我们来看一下页面效果,现在我们的整个节点我们往前拖,出现这条横线,那就拖前面了,往后拖还是这条横线,包括我们想给里边拖,把这个节点拉上,放到它的身体上好,现在呢就拖到了里边,但是呢,我们现在还发现一个问题,就是我们这么一拖拽以后呢,我们这个层级变成了四层。
01:01
嗯,而我们分类呢,我们现在业务要求只有三级分类,所以我们这个节点啊,到底能不能拖到指定位置,我们是需要判断的,这一块呢,也可以来参照element UI,在拖拽节点的时候呢,我们还有一个属性叫a drop drop是可以在拖拽时判定我们当前节点能否被放置在指定位置,Allow drop呢,它是一个函数,这个函数有三个参数,这三个参数呢,其中第一个。Dragon node就是当前正在拖拽的节点。Type指的是我们当前节点被放了到了哪些位置,比如有三种情况,Brave,那就是前边,Inner就是里边,Nest就是后边,那放到了哪个节点的前后里边,那就是这个节点,所以呢,这有三个参数,我们可以看一下示例代码有没有用到这一块,我们看到这个示例代码EL tree里边呢,也有一个叫a allow drop a allow drop a drop呢,它触发一个函数,在这这个函数呢,可以做我们业务判断,通过返回true false。
02:06
E处,以决定这个节点能否被放置在指定位置,那我们把这个也加上好,我们加上drop ctrl c。同样复制到这来,那到底能不能allow off,我们给它把这个函数呢,也放在这,我们要经过我们自己业务的判断来决定是否可以被放置在指定位置,把它复制过来,好放在这,Out shift f,我们代码整理一下,但这一块呢,整个返回触货false,那比如我们现在直接返回false,那相当于我们所有的节点呢,都是不可被拖拽到指定位置的,我们可以看一下效果,我们刷新页面,手机我们来打开,比如我们拉着手机我来拖,虽然能拖动,但是我们想要给任何位置放,这都是一个静止标志。那我们怎样能允许他拖到指定位置呢?其实这个业务判断有一个核心,就是我们无论拖动任何节点,这个节点最终的总层级数不能大于三。比如我把手机通讯这整个节点,我想拖到运营商里边,这是不可以的,因为手机通讯呢,现在它已经是两层了,而运营商带上它的最外层也两层了,我们要拖到它里边,那就变成四层了。所以能不能拖动只需要做一个判断,那就是当前节点如果是放在某个节点的里边,那就是当前节点的总层数加上它负节点以及外层节点的总层数不能大于三,如果放到了某个节点的后边,比如放在手机配件的后边,那就是当前节点的总层数加上它的负节点及以上的层数不能大于三。所以呢,我们最终的核心,我们只需要判断被拖动的。被拖动的当。
03:56
偏节点以及以及所在的负节点。
04:05
总层数不能大于三,所以呢,我们现在要做的第一件事就是先判断被拖动的当前节点层数总共是几,那我们先来做第一件事,我们判断被拖动的当前节点总层数,那被拖动的当前节点总层数,我们怎么知道哪个是被拖动的当前节点,我们可以在控制台打印一下这三个参数,诶,我们说了。前面这个参数是当前节点,这是它放到了哪个位置,这个呢是放到了哪个节点的这些位置,所以呢,我们把这三个参数打印来观察一下,是不是我们说的这样。哎,复制保存,我们现在呢,来参照页面效果,我们来看拖动的整个效果F12。把这一块控制台清空,比如我把这个对讲机给手机里边拖,哎,我们放开,比如这一块呢,就会出现这些打印,比如a allow drop,我们调用了这个函数,前面第一个节点,第二个节点以及它的位置,前面有in,接下来有next,那么第一个节点的名字是什么?当前节点的data里边是我们真正封装的节点数据,它的名字叫对讲机,诶,我们就是它,它被拖到哪个节点呢?我们之前一直想把它给手机节点的里边放,我们看现在呢,是手机节点。
05:33
它的这个位置呢,有几种情况,有next,有当然也有pre,我们可以看一下,哎,有pro,那所以呢,我们现在要做的第一件事就是来计算出这个节点的目前总层数,假设呢,我们有一个方法,我们就来统计count。Node的level来统计我们当前节点的这个总层数,这就是我们当前正在拖动的节点,我们希望它呢能给我们返回一个总层数。
06:05
Level。来,我们把这个方法呢写过来,把这个方法名我们拿过来,我们传入我们要统计的这个节点,好复制过来,这个怎么统计呢?我们展开页面,其实啊,我们就是来看,如果当前节点,我们被拖动的当前节点有子节点,假设呢,子节点呢还有子节点,子节点呢还有子节点等等,这其实是一个递归,查找它的所有子节点,那最快的办法就是我们只要找到所有的子节点最深的层级,假设最深的层级是三,跟当前层级是二,那么它两个呢,合起来就是三减二加一,总共就是两级,再加上负节点所在的层级,负节点的层级呢是在这统计的,我们每拖动的这个节点,它有一个呢,叫parent,叫负节点,此时在几级,这有一个叫level。
07:05
只要它们合起来不大于三就行,所以我们这个方法的作用就是统计当前。被拖动节点的总层数,那怎么统计呢?我们刚才看到了,其实就是呢,找到所有子节点。求出最大深度,那怎么找呢?这是当前正在拖动的节点,我们可以现现在找到节点的真正内容,节点的真正内容是在贝塔里边,所以我们给他传的时候,传的是drag点贝塔,那这就是我们真正的这个节点,我们想要求出这个节点的最大深度,我们先来判断,如果说当前节点,游子节点怎么叫游子节点呢?点一个当前节点有一个属性叫丘疹,点一个丘疹它呢不是空的,并且它的这个丘疹。
08:04
点lengths,因为它是一个数组,数组的长度呢是大于零,说明呢,我们是由子节点的,那由子节点我们就来变历for,我们来变历遍历它所有的子节点,Let从I从零开始到I小于我们当前节点子节点的长度A加加。我们取出当前节点,当前节点呢,那就是。No children正哎,我来判断,如果说当前节点的这个深度,诶,我们这个当前节点啊,我们给它有一个值叫cant level,点一个我们存了一个cant level这个值,如果这个值大于假设我们初始化有一个值,我们在这儿放一下,我们是要统计它的这个最大的level层级,最大level假设呢,现在默认是一。
09:04
或者呢,我们给它默认给一个零,如果说我们的这个level大于我存储的这个max level,那我们就给它交换值,那this max level就等于我们当前节点的深度值。而且呢,这是一个递归,我们每一个节点呢,如果它的深度大于当前深度,给它赋值,同时要看我们正在便利的这个节点又有没有此节点,所以我们还是继续调用这个方法,继续调用这个方法来看一下当前正在变历的这个节点还有没有其他子节点,继续统计深度。这样呢,我们这个递归找到当前节点的子节点最大深度的方法,我们就已经写完了,那我们最终呢,这个方法调用完,我们就会求出最大的这个深度。
10:09
那这个最大深度加上当前正在拖动的节点,它所在的负节点的深度只要不大于四就行了,那就是当前正在拖动的节点加上负节点所在的深度不大于哎,不大于三即可。我们来看一下这个方法,那当前正在拖动的这个节点,我们来看一下。我把这一块呢清空。我们来准备好,比如我要拖动选号中心,我把它呢拖动到合约机的前边,发现呢,这一块方法没定义,我们要调用方法,必须用view的实例this对象来调用保存,我们来重新来测试。
11:06
我们现在来拖动我们三生三世,我拖动到我们的手机前边,那现在呢,我们当前正在拖动的这个节点,我们来看一下正在拖动的节点是它,然后呢,它所处的负节点,负节点的层级,我们来看负节点的层级是二,因为我们要把它拖动到手机前边,那我们是在手机通讯里边,那它的负节点层级是二,加上当前节点的最大子节点深度,只要不大于三就行了,那当前节点的最大子节点深度我们是拿这个求的,求出来以后呢,会得到must level这个值,console.log正在拖动节点的这个深度,这个深度呢,我们来给它打印一下我们这个纸。看一下页面效果保存,我们来看一下页面,现在呢,假设我们来拖动手机通讯,把它拖到家用电器里边,这块呢,还会有报错,又是这个count node6没定义,没定义的原因是我们在这递归调用的时候,调用方法都要用5U的实例this来调用,保存好重新测试。现在呢,我们来拖动,我把手机通讯整个目录呢,我拖到家用电器的里边,那我想拖到这儿,首先它打印的深度是三,也就说手机通讯的深度是三,并不是因为它的深度是三,而它这个子节点的最大level是三,那它的深度应该是子节点的最大level减去当前节点的level,然后再加一,这是三减二加一是两层深度,所以我们真正的深度来求一下z.max level减去,减去我们当前正在拖动的这。
13:00
个节点,那就是data这个节点,这个节点的can level。它两个相减呢,再加一,这才是深度。再加上一,这就是我们要计算的当前深度,我们let let一个D,好像我们这个深度呢,知道了,那我们真正的深度呢,就应该是这个,我把它复制来,那能不能被拖到指定的位置,那我们就需要做一个判断,怎么判断呢?那就是只要这个深度啊,加上我们想把手机通讯拖到比如运营商里边拖到哪个节点,这有一个节点,所以呢,我要加上我们被拖动到某一个位置的这个节点的深度,比如这个节点的乘积呢是三,如果它俩加一起大于三了,那就不行。我们可以再来看一下,我把手机通讯给运营商里边拖,那运营商的这个深度啊,应该不高,我们给运营商里边拖,我们来看一下我们这个节点是不是叫运营商好叫运营商,而他所在的level。
14:15
它是二,所以呢,只要这个二加上我们这个深度不大于三就行了,那最终就是我们的算的这个深度加上,加上我们当前这个节点被拖动到哪个位置。而且呢,我们不能只来加,我们说的这个只来加的情况,那是我们把它拖到里边,那如果我把它拖到它的前后左右,所以不用看当前节点的深度,只用看它父亲的深度就行了,所以我们在这要判断一下,如果说这个tap,我们这个tap啊有几种类型,如果type等等,应它呢,是拖到某一个节点里边的,所以我们深度是相加关系,我们就返回这个被F深度加上,我们当前要拖到这个节点,这个节点呢有一个level,我们来看一下,那就是我们这个节点,这个节点呢,直接有一个属性叫雷网。
15:15
加上这个level小于等于三吗?如果小于等于三,它就会返回处,那就是能拖动,如果大于三,那就是返回false不能拖动,这是婴儿的情况,否则无无论是前边还是后边,我们的这个声度呢,只需要加上所在位置这个节点负节点的深度,所以说你把这个变一下。那现在呢,我们就来算一下,应该是return return什么呢?我们现在是这个深度,加上它所在的负节点drop node job node呢,那就是第二个,第二个的负节点在它的负节点,负节点呢,也有它的level层级,这个层级呢是一,所以我们只需要加上它负节点的这个层级,如果小于等于三,那就是能能拖动,否则呢就不能拖动,这样我们整个方法返回一个触破我来保存。
16:16
看一下页面效果,现在我把手机给家用电器里边拖,诶这是拖不了的,只能拖前后,我们给里边是拖不了的,但是呢,我们现在把手机通讯给家用电器里边拖,我们来拖到电器里边,好,我们放进来,我发现呢,现在是拖进来了,拖进来呢默认还放到最后一个了,现在我们假设要把厨房小店。给手机通讯里边拖又拖不了,但是把手机通讯里边的子节点给我们的厨房小店里边拖,诶我们发现呢能拖进去。我们一直在后边,这就好了,那我们整个拖拽判断就完成了。
我来说两句