关于有向无环图在vue项目中的使用和安装,已经有很多的文章有过介绍了,我在这就不再重复这些东西,本文主要介绍的是在使用dag-diagram(一下简称dag)这个插件时的小技巧或者说是一些经验吧

1、自定义右击事件偶现问题
	<DAGBoard
        :data-all="DataAll"
        @updateDAG="updateDAG"
        @editNodeDetails="editNodeDetails"
        @doSthPersonal="doSthPersonal"
    />

插件中有一个doSthPersonal事件,就是用来自定义右击事件的,可以在这个事件中写你所要自定义的右击事件的代码,
但是有一个前提是你需要在每个节点的rightClickEvent中添加这个自定义事件的eventName和label
下面的代码是dag插件中的源码:

const rightClickEvent = this.DataAll.nodes[i].rightClickEvent || null

因此我们可以在自己的项目的updateDAG事件中这样写

this.DataAll.nodes[i].rightClickEvent = [
                            {
                                label: 'CREATE NODE',
                                eventName: 'creatednode',
                            },
                            {
                                label: 'DELETE NODE INFO',
                                eventName: 'deletenode',
                            },
                        ];

如果只是简单的这样写上的话你会发现,自定义事件在你第一次去右击的时候是不会出来的,但是第二次就会有了,这是因为updateDAG方法只有节点在幕布内发生变化时(移动或删除)才会执行,在将节点拖入到幕布中的这一事件中是不会触发的
所以我使用了watch来监听this.DataAll.nodes的长度,来添加自定义事件,因为nodes的长度在节点被拖入幕布的时候就会发生变化

'DataAll.nodes.length': {
            handler() {
                for (let i = 0; i < this.DataAll.nodes.length; i += 1) {
                        this.DataAll.nodes[i].rightClickEvent = [
                            {
                                label: 'CREATE NODE',
                                eventName: 'creatednode',
                            },
                            {
                                label: 'DELETE NODE INFO',
                                eventName: 'deletenode',
                            },
                        ];
                }
            },
            deep: true,
        },

这样就可以解决第一次点击节点时,自定义事件不出现的问题

2、节点删除再添加反复操作几次会出现,删除一个节点多个节点一起消失

问题原因:
在dag插件中,每个节点的id都是由this.DataAll.nodes.length + 100组成的,如果你是删除节点的时候是先删除的最后添加的节点,那没问题,但是如果删除的是非最后一个节点,那就会出现新添加的节点id和已存在的节点id重复的问题,所以当你移动新添加的节点或者删除新添加的节点时,会有另一个节点随之消失
解决方法:
所以在给节点id赋值时我们应该添加一种情况
就是当用户执行删除操作后,应该将id的值设置为最后添加的id值+1+100,这样就不会出现有重复id的情况

if (this.DataAll.nodes.length) {
   id1 = this.DataAll.nodes[len - 1].id + 1 - 100 + 100;
 } else {
     id1 = this.DataAll.nodes.length + 100;
 }
 this.DataAll.nodes.push({
     ...params.desp,
     id: id1,
     in_ports: [0, 1, 2, 3, 4],
     out_ports: [0, 1, 2, 3, 4],
 });
3、检测是否成环

这个功能我在看插件源码的时候它是有写这部分校验的,但是不知道为什么我在dag这个项目中数据成环后并没有提示,在我自己的项目中也并未实现改功能
于是我就把插件中的关于检测是否成环这部分代码拿出来,直接写在了我自己的 项目中
其实用的还是插件中的源码

// 检测是否成环
            this.DataAll.edges.forEach((item) => {
                let isCircle = false;
                // 出口 入口id
                const { dst_node_id } = item; // eslint-disable-line
                const checkCircle = (dstNodeId, nth) => {
                    if (nth > this.DataAll.nodes.length) {
                        isCircle = true;
                        return false;
                    }
                    this.DataAll.edges.forEach((item) => {
                        if (item.src_node_id === dstNodeId) {
                            console.log(
                                '目标节点是',
                                item.src_node_id,
                                '次数为',
                                nth,
                            );
                            checkCircle(item.dst_node_id, ++nth); // eslint-disable-line
                        }
                    });
                    return false;
                };
                checkCircle(dst_node_id, 1);
                if (isCircle) {
                    this.DataAll.edges.pop();
                    // alert('禁止成环');
                    this.$Message.error('禁止成环');
                }
            });

我是写在了保存按钮中,我试了dag插件带的那几个方法,并未生效,所以就只能在保存时校验
如果有更好的方法,希望大家不吝指教~~

Logo

前往低代码交流专区

更多推荐