清缓存!!!!!!
1.4
- AntV (Tree) (eCharts) 使用过程出现的问题
1. 更新数据时,会再次出现一个画布进行渲染,此时需要使用 this.tree.destroy() 销毁上一次的画布;
2. 初始化树状图时,发现不符合代码的渲染逻辑,此时可以检查 版本号是否一致
3. 树状图 渲染时可以指定 固定ID,也可以指定一个 container 容器
<div ref={(container) => { me.container = container; }} > </div>
4. 树状图的数据 需要一个根元素节点
let data = { 'name': 'All' , 'chidlren': '这个地方放数据' }
1.5
- fulFillConfigs 项目 (时间片规则展示)
1. 用户在进行搜索时,注意判断用户输入值以后有两种情况,第一是更改了显示的内容 , 第二是用户输入文字以后再删除了所有的文字,此时需要回到初始状态
2. push 前记得commit , commit前记得看看是不是所在分支。
3. 封装tree的通用函数转换时,会报错说每个元素需要有唯一的key,此时需要去看封装的方法中对象的key是什么,后端传过来的数据可能会有重复的id或者那么字段之类的。
1.8
- fulFillConfigs 项目 (时间片规则展示)
1. tree 里面的数据,每个节点的key必须不一样,否则会出现点击任意一个节点展开时,对应的相同的key的别的节点也会自动展开。
2. eval 方法可以使用在canvas画布设置大小
eval( window.innerHeight - 100 )
1.9
- fulFillConfigs 项目 (时间片规则展示)
1. 当key不同,name相同时,可以遍历数组若有重复,将字符串加一个空格即可;
2. 代码注释要写好,如果是通用方法,可以写成组件形式
- 总结
1. 用面向对象思想去考虑问题,从更大的格局去考虑整体的代码书写逻辑,书写的时候会麻烦一些,但是出现问题时,可以更快速的定位问题,具体到细节方面:
代码注释不要怕麻烦,要写清楚 但是一些很简单的可以不写 注释太多也会造成阅读不方便
如果是通用方法,可以尝试写一个组件,也可以在已有组件中查找一些已经写好的组件
查找问题时,可以多用 debugger 模式
可以把 actions 里面的一些方法 写得更小 分的更细致 这样也可以更快的定位问题
1.10
- 使用搜索框时,显示结果只显示和关键字相关的数据,两种方法
1. 从叶子节点开始遍历,判断是否满足,不满足用splice删去,满足留下
setSearchTree(data, value) {
let temp = data.concat();
for (let i=temp.length-1 ; i>=0 ; i--) {
let item = temp[i];
if(item.children && item.children.length > 0) {
let res = this.setSearchTree(item.children, value);
if(res.length == 0 && item.key.indexOf(value.trim()) == -1) {
temp.splice(i, 1);
}else {
item.children = res;
}
}else {
if(item.key.indexOf(value.trim()) == -1) {
temp.splice(i, 1);
}
}
}
return temp;
}
- 给叶子节点添加标示(level : 0_0_0_1)(递归),目的是看到某个叶子节点,就可以找到他的任意祖先节点,此时将所有叶子节点归到一起与关键词进行判断,返回的结果重新包装。
- 首先给每个节点加一个标识字段(isShow),这个字段代表每个节点自描述自身是否显示,接下来递归进行循环,此时运用算法,从叶子结点开始向上递归,判断某个节点和他兄弟节点的isShow,这是会有三种情况,所有的都是true,所有的都是false,有true、也有false,再判断此时这些节点的父节点(只有一个),父节点会有两种情况,集合起来,会有三种情况需要进行改变,而改变只有两种方式,一种是父节点是true,字节点都是false,此时需要进行向下递归,将下面的所有节点都变为true,另外两种情况是子节点都是true和有true和false并且父元素是false,此时都是改变父元素为true,递归遍历结束后,再递归将所有的false的节点删除掉。
* @func setTreeAddLevelAndIsShow
* @desc 递归函数 给数据加上 level 和 isShow 字段
* @param {Arr} data -- 原始数组
* @param {Str} level -- 格式:level :0_0_1_2
* @param {Str} value -- 搜索的关键字
* @return {Arr} TreeAddLevelAndIsShow 返回带level和isShow的数组
**/
setTreeAddLevelAndIsShow(datal, value) {
// let temp = 0;
let treeAddLevelAndIsShow = deepClone(data);
treeAddLevelAndIsShow.map(item => {
// item.level = `${level}${level ? '_' : ''}${temp++}`;
let flag = item.key.indexOf(value.trim()) > -1 ||
( item.dataName ? (item.dataName.indexOf(value.trim()) > -1) : '' )
if(flag) {
item.isShow = true;
}else {
item.isShow = false;
}
if(item.children && item.children.length > 0) {
item.children = this.setTreeAddLevelAndIsShow(item.children, value);
}
})
return treeAddLevelAndIsShow;
}
/**
* @func judgeTreeNodeShow
* @desc 通过isShow判断每个节点是否需要显示
* @param {Arr} data -- 原始数组
* @return {Arr} newData -- 返回的新数组
**/
judgeTreeNodeShow(data) {
let newData = deepClone(data);
newData.map(item => {
if(item.children && item.children.length > 0) {
item.children = this.judgeTreeNodeShow(item.children);
if(item.isShow) {
switch(this.judgeChildrenType(item.children)) {
case 0 :
item.children = this.repeatChangeIsShow(item.children);
break;
case 1 :
// do nothing
break;
case 2 :
// do nothing
break;
}
}else {
switch(this.judgeChildrenType(item.children)) {
case 0 :
// do nothing
break;
case 1 :
case 2 :
item.isShow = true;
break;
}
}
}
});
return newData;
}
/**
* @func judgeChildrenType
* @desc 判断传入数据的children的类型种类
* @param {arr} data
* @return {Num} 0-都是false 1-都是true 2-true和false都有
**/
judgeChildrenType(data) {
let newData = deepClone(data);
let showFlag = newData.some(item => {
return item.isShow==true
})
let deleteFlag = newData.some(item => {
return item.isShow==false
})
if(showFlag && deleteFlag) {
return 2;
}else if(showFlag && !deleteFlag) {
return 1;
}else {
return 0;
}
}
/**
* @func repeatChangeIsShow
* @desc 递归从根到下改变每个节点的isShow为true
* @param {Arr} data
* @return {Arr} newData
**/
repeatChangeIsShow(data) {
let newData = deepClone(data);
newData.map(item => {
item.isShow = true;
if(item.children && item.children.length > 0) {
this.repeatChangeIsShow(item.children)
}
})
return newData;
},
/**
* @func recoverTreeData
* @desc 恢复 tree 的结构
* @param {Arr} data -- 原始数组
* @return {Arr} newData -- 新数据
**/
deleteUselessTreeNode(data) {
let newData = deepClone(data);
for(let i=newData.length-1 ; i>=0 ; i--) {
let item = newData[i];
if(item.isShow == false) {
newData.splice(i, 1);
}else {
if(item.children && item.children.length>0) {
item.children = this.deleteUselessTreeNode(item.children);
}
}
}
return newData;
}
1.22
- 履约 时间片规则展示 tree 后端返回数据结构更改,其中需要显示的字段relateName要传递一个包含id的数组到后端,多次异步ajax请求数据,此时出现两个问题:
1. 如果每次请求回来的数据都cursor.set,会造成只有最后一次的ajax请求的数据储存成功。 解决:使用全局变量,每次数据回来时,都改变的是同一个全局变量。
2. 按照第一种方案进行处理,出现第二个问题,如果ajax数据回来,都修改的是同一个全局变量,此时会出现ajax接口调用成功,数据返回正常,但是ajax不走then,走catch,暂时认为是因为ajax每次都修改的都是同一个变量,会出现冲突。解决: 运用promise.all方法进行处理,等待所有的异步操作完成后,一次性给tree赋值。
1.23
- 完成 PageDialog 组件的编写,启发的地方是,当考虑一个组件编写的时候,应该多加考虑复用性以及兼容性,但如果兼容性太过于复杂,可以拆分成更小的组件来减少耦合。
- 在编写的最开始,可以先设计好,应该传入哪些参数,并写好注释。
1.24
- 在写一个单独的css样式时,注意尽量不要直接使用标签的名字,这样后面写相同标签时,会出现bug。
1.25
- 页面初始化时,多次dispatch发送请求,多次ajax,多次cursor.set赋值,会出现冲突,前几次的赋值会被后几次覆盖,导致赋值失败,其他地方取值为none,解决办法为,第一次dispatch结束,赋值结束,再进行第二次赋值,以此循环。
1.30
- 后端需要字段需要带(\n)字符串,此时可以使用Input自带属性多行属性,此时传给后台,需要使用JSON.stringify()来将回车转换成 (\n) 。