aqyj/components/path-view/index.js

243 lines
6.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// components/path-view/index.js
import toTree from './toTree';
Component({
properties: {
value: {
type: Array,
value: [],
observer() {
this.initView();
}
},
// 非树形数据仅在value无传参时生效
unnormalizedValue: {
type: Array,
value: [],
observer() {
this.initView();
}
},
fatherKey: {
type: String,
value: 'pid'
},
selfKey: {
type: String,
value: 'id'
},
rootValue: {
type: null,
value: null
},
pathMode: {
type: String,
value: 'mode1'
},
firstFloorTxt: {
type: String,
value: '顶级'
},
btnTxt: {
type: String,
value: '选择'
},
contentKey: {
type: String,
value: 'name'
},
// 保持位置
// 如果开启,数据动态更新后,会保持和更新前父元素对应的界面一致
// 这里是通过记录下更新前的父元素的唯一标识符id或是selfKey中设定的键对应的值在更新后找回显示出来
// 所以就算更新后路径变了(父元素本来在第四层,变成了第二层之类),仍然能显示父元素的相应界面
keepLoc: {
type: Boolean,
value: false
}
},
data: {
outValue: [],
currentPath: [],
// 判断当前是否已正在执行修改路径的方法
isChange: false,
// 映射value值存放树形数据
normalValue: [],
currentFatherId: null
},
methods: {
initView() {
if (this.properties.keepLoc) {
if (this.data.outValue.length > 0) {
// 记录下当前界面元素的父节点id
let fatherId = this.properties.fatherKey;
this.setData({
currentFatherId: this.data.outValue[0][fatherId] || null
});
}
}
// 优先使用value
if (this.properties.value.length > 0) {
this.setData({
normalValue: this.properties.value
});
} else {
// 将unnormalizedValue标准化
this.setData({
normalValue: this.normalizeValue()
});
}
if (this.properties.keepLoc && this.data.currentFatherId !== null) {
// 得到父元素的位置
let fatherNodeLocation = this.searchLocById(this.data.currentFatherId);
// 父元素的位置即是我们希望得到的当前路径
let currentPath = fatherNodeLocation;
this.switchPath(currentPath);
} else {
// 设置初始的输出值
this.setData({
outValue: this.data.normalValue,
currentPath: []
});
}
},
tapItem(e) {
// 如果正在执行修改路径的方法
if (this.data.isChange) {
return;
}
this.setData({
isChange: true
});
// 获取当前点击的索引
const currentIndex = e.currentTarget.dataset.index;
const currentText = e.currentTarget.dataset.text;
// 如果当前点击的标签还有下一级,就将路径改变
if (this.data.outValue[currentIndex].children) {
// 添加索引如路径
this.setData({
currentPath: [
...this.data.currentPath,
{ text: currentText, index: currentIndex }
]
});
this.selPath();
}
this.setData({
isChange: false
});
},
// 选择路径
// pathsIndex 是 paths 的索引
selPath(pathsIndex = this.data.currentPath.length - 1) {
// 判断是否在第一级
if (this.data.currentPath.length === 0) {
return;
}
// 根据路径修改 outValue
let tmpValue = this.data.normalValue;
// 如果 pathsIndex 是 -1 就应该要回到第一级
if (pathsIndex === -1) {
this.setData({
currentPath: [],
outValue: tmpValue
});
return;
}
for (let i = 0; i <= pathsIndex; i++) {
let item = this.data.currentPath[i].index;
tmpValue = tmpValue[item]['children'];
}
// 更新 outValue , currentPath
let endIndex = pathsIndex + 1;
this.setData({
outValue: tmpValue,
currentPath: this.data.currentPath.slice(0, endIndex)
});
},
toPath(e) {
// 如果正在执行修改路径的方法
if (this.data.isChange) {
return;
}
this.setData({
isChange: true
});
// 获取当前点击的索引
const index =
e.currentTarget.dataset.index != undefined
? e.currentTarget.dataset.index
: this.data.currentPath.length - 1;
this.selPath(index - 1);
this.setData({
isChange: false
});
},
tapBtn(e) {
this.triggerEvent('tapBtn', e.currentTarget.dataset.item);
},
// 将非标准值标准化
normalizeValue() {
return toTree({
value: this.properties.unnormalizedValue,
fatherKey: this.properties.fatherKey,
selfKey: this.properties.selfKey,
rootValue:
this.properties.rootValue === null
? undefined
: this.properties.rootValue
});
},
// 通过唯一标识符找到元素的所在位置
// 这里特意用了loclocation表示位置而不是path二者的区别是loc还包括了元素自身而path不包括元素自身
// 如树形数据[{id:1,name:'1'}],id:1的位置是[1],而它的路径是[]
searchLocById(id) {
if (id == null) {
return null;
}
let tree = JSON.parse(JSON.stringify(this.data.normalValue));
for (let i = 0; i < tree.length; i++) {
tree[i].__location = [i];
if (id === tree[i][this.properties.selfKey]) {
return tree[i].__location;
}
}
var stark = [];
stark = stark.concat(tree);
while (stark.length) {
var temp = stark.shift();
if (temp.children) {
for (let j = 0; j < temp.children.length; j++) {
temp.children[j].__location = [...temp.__location, j];
if (id === temp.children[j][this.properties.selfKey]) {
return temp.children[j].__location;
}
}
// 当前节点有子节点时,将子节点放到当前的栈的前面
stark = temp.children.concat(stark);
}
}
// 如果找不到对应id的位置
return null;
},
// 直接跳转到指定路径
switchPath(pathArr = []) {
let tmpValue = JSON.parse(JSON.stringify(this.data.normalValue));
let currentPath = [];
for (let i = 0; i < pathArr.length; i++) {
let index = pathArr[i];
let text = tmpValue[index][this.properties.contentKey];
tmpValue = tmpValue[index]['children'];
currentPath.push({
text,
index
});
}
// 更新 outValue , currentPath
this.setData({
outValue: tmpValue,
currentPath
});
}
}
});