今天需要做一个树的搜索。并且是带结构的。
indexOf() 作为successearch()方法,也就是靠着字符串的对比来实现搜索,其实这样做有点捞,但是没有办法,因为现在开发没有写相关的工具方法,所以只能这样的简易的搜索实现,原本我是直接对比树的节点。但是,这样是有问题的。
问题在于我直接搜索一棵树的节点,有点节点是在展开的时候创建的,这样就很尴尬了,我没有办法去搜索一个没有被创建的节点,但是好在父级节点是持有他儿子节点的属性的 类似 id caption data等关键的信息。
找到这些信息的时候我一度想去createItem 制造这些节点,但是呢,dom操作永远是和消耗时间的。这里其实也不需要这些节点被创建出来。我需要做的是当一个节点有子节点的时候,去递归一下即可。这样就能搜索出所有的节点了。
代码:
let search = (data: any[], keyword: string) => {
data && data.forEach(e => {
let edata = !e.name ? e.getData() : e;
if (isMatchKeyWord(edata, keyword)) {
result.push(e);
}
if (edata.items == 0) {
return;
}
search(edata.items, keyword);
});
}
这样确实能够将搜索出来的数据全部加到结果集里面。但是这样做其实是不够的,因为在搜索的时候,按照name和caption来搜索,很有可能是不同的目录下面caption一样的,所以搜索结果应该带有自己的结构属性。例如a/b
所以我们应该对res结果集做一些操作:将里面有父级节点并且父级节点相同的节点构建出他们的父级节点,然后再push到新的res结果集里面。
我是这样做的:
for (let i = 0; i < result.length; i++) {
let item = result[i];
item.expanded = true;
if (!(item).parent) {
if (!!mid && !romval(res, mid)) {
res.push(mid);
}
res.push(item);
continue;
}
if (!mid) {
mid = item.parent;
mid.items = [];
mid.items.push(item);
mid.expanded = true;
continue;
}
if (mid == item.parent) {
mid.items.push(item);
}
if (mid != item.parent) {
romval(res,mid);
res.push(mid);
mid = item.parent;
}
if (i == result.length - 1) {
romval(res,mid);
res.push(mid);
}
}
mid用来缓存当前节点的父节点。其实在push的时候有一个共同的地方。就是push之前得检查一下mid在不在里面,不在里面就push。 romval 是用来清除res里面id相同的项。为什么要这样做呢?因为很可能父级节点里面有你要搜索的内容。所以得去重。
好了 到此结束 !