Sat*_*tAj 8 tree filter angular-material2 angular angular6
我正在使用垫树角材料组件.这是一个很好的组件,有一些非常有用的功能,如多选,全部展开/全部折叠.我无法在任何API中找到任何树过滤功能.有没有人遇到这个功能或做任何工作来获得mat-tree过滤器?
Ami*_*h B 16
如果任何人需要在不修改数据源的情况下直观地过滤 mat 树,那么请选择此解决方案。
基本上,这个想法是隐藏不属于搜索字符串的节点。
输入栏
<input [(ngModel)]="searchString" />
Run Code Online (Sandbox Code Playgroud)
调用叶节点的过滤函数(这是在第一个 mat-tree-node 中完成的)
<mat-tree-node
*matTreeNodeDef="let node"
[style.display]="
filterLeafNode(node) ? 'none' : 'block'
"
.....
......
Run Code Online (Sandbox Code Playgroud)
对叶节点以外的节点调用过滤函数(这是在第二个 mat-tree-node 中完成的)
<mat-tree-node
*matTreeNodeDef="let node; when: hasChild"
[style.display]="filterParentNode(node) ? 'none' : 'block'"
.....
.....
Run Code Online (Sandbox Code Playgroud)
filterLeafNode 函数
filterLeafNode(node: TodoItemFlatNode): boolean {
if (!this.searchString) {
return false
}
return node.item.toLowerCase()
.indexOf(this.searchString?.toLowerCase()) === -1
}
Run Code Online (Sandbox Code Playgroud)
过滤父节点函数
filterParentNode(node: TodoItemFlatNode): boolean {
if (
!this.searchString ||
node.item.toLowerCase()
.indexOf(
this.searchString?.toLowerCase()
) !== -1
) {
return false
}
const descendants = this.treeControl.getDescendants(node)
if (
descendants.some(
(descendantNode) =>
descendantNode.item
.toLowerCase()
.indexOf(this.searchString?.toLowerCase()) !== -1
)
) {
return false
}
return true
}
Run Code Online (Sandbox Code Playgroud)
小智 5
在完成相同任务几天后,这里提供一些提示:我正在使用输入事件来跟踪用户输入:
<input matInput class="form-control"
(input)="filterChanged($event.target.value)"
placeholder="Search Skill">
Run Code Online (Sandbox Code Playgroud)
在此过滤器上,我附加了一个主题,因此我可以订阅它:
searchFilter: Subject<string> = new Subject<string>();
filterChanged(filter: string): void {
this.searchFilter.next(filter);
}
Run Code Online (Sandbox Code Playgroud)
为了使用户使用起来更加顺畅,通常,我们希望延迟您可以执行的搜索执行debounceTime。
this.searchFilter.pipe(debounceTime(500), distinctUntilChanged())
.subscribe(value => {
if (value && value.length >= 3) {
this.filterByName(value);
} else {
this.clearFilter();
}
});
Run Code Online (Sandbox Code Playgroud)
为了执行搜索,我使用css类隐藏并显示了节点。这是直接在扁平且易于过滤的演示文稿集合上完成的。
treeControl: FlatTreeControl<SkillFlatNode>;
this.treeControl.dataNodes
Run Code Online (Sandbox Code Playgroud)
首先,我全部隐藏,然后仅显示符合条件的那些。最后,我想向他们的父母展示,但这是针对我的树形结构的。
private filterByName(term: string): void {
const filteredItems = this.treeControl.dataNodes.filter(
x => x.value.DisplayName.toLowerCase().indexOf(term.toLowerCase()) === -1
);
filteredItems.map(x => {
x.visible = false;
});
const visibleItems = this.treeControl.dataNodes.filter(
x => x.value.IsSkill &&
x.value.DisplayName.toLowerCase().indexOf(term.toLowerCase()) > -1
);
visibleItems.map( x => {
x.visible = true;
this.markParent(x);
});
}
Run Code Online (Sandbox Code Playgroud)
最后,这是清除过滤器:
private clearFilter(): void {
this.treeControl.dataNodes.forEach(x => x.visible = true);
}
Run Code Online (Sandbox Code Playgroud)
不要像我一样犯同样的错误,并尝试过滤输入集合(this.dataSource.data在我的情况下),因为您会丢失选择,或者必须将其映射回演示文稿。这是我的初始数据:
this.treeFlattener = new MatTreeFlattener(
this.transformer, this._getLevel, this._isExpandable, this._getChildren
);
this.treeControl = new FlatTreeControl<SkillFlatNode>(
this._getLevel, this._isExpandable
);
this.dataSource = new MatTreeFlatDataSource(
this.treeControl, this.treeFlattener
);
skillService.dataChange.subscribe(data => {
this.dataSource.data = data;
});
Run Code Online (Sandbox Code Playgroud)
我通过创建一个新的数据源(已过滤)解决了这个问题。
我将解释共享链接的示例:我使用filter(filterText: string)in 过滤了数据ChecklistDatabase并触发了一个dataChange事件。然后datasource.data由中的已处理事件更改TreeChecklistExample。因此,数据源已被修改。
filter(filterText: string) {
let filteredTreeData;
if (filterText) {
filteredTreeData = this.treeData.filter(
//There is filter function in the sample
);
} else {
filteredTreeData = this.treeData;
}
// file node as children.
const data = this.buildFileTree(filteredTreeData, '0');
// Notify the change. !!!IMPORTANT
this.dataChange.next(data);
}
Run Code Online (Sandbox Code Playgroud)
我能够通过使用简单的递归来过滤树。下面是代码片段:
该filter()函数是在 上调用(keyup)的input type="text"。cloneDeep函数是从 lodash 导入的import * as cloneDeep from 'lodash/cloneDeep';
this.searchString 是过滤器文本的字符串值。
filter() {
const clonedTreeLocal = cloneDeep(this.clonedTree);
this.recursiveNodeEliminator(clonedTreeLocal);
this.dataSource.data = clonedTreeLocal;
this.treeControl.expandAll();
}
Run Code Online (Sandbox Code Playgroud)
树结构由接口定义
export interface ITreeDataStructure {
Id?: number;
name: string;
type: string;
children?: Array<ITreeDataStructure>;
}
Run Code Online (Sandbox Code Playgroud)
实际的过滤是由函数完成的 recursiveNodeEliminator
recursiveNodeEliminator(tree: Array<ITreeDataStructure>): boolean {
for (let index = tree.length - 1; index >= 0; index--) {
const node = tree[index];
if (node.children) {
const parentCanBeEliminated = this.recursiveNodeEliminator(node.children);
if (parentCanBeEliminated) {
if (node.name.toLocaleLowerCase().indexOf(this.searchString.toLocaleLowerCase()) === -1) {
tree.splice(index, 1);
}
}
} else {
// Its a leaf node. No more branches.
if (node.name.toLocaleLowerCase().indexOf(this.searchString.toLocaleLowerCase()) === -1) {
tree.splice(index, 1);
}
}
}
return tree.length === 0;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8783 次 |
| 最近记录: |