代码之家  ›  专栏  ›  技术社区  ›  SatAj

如何过滤材质树组件角材质6.0.1

  •  6
  • SatAj  · 技术社区  · 8 年前

    我使用的是mat-tree角材质组件。 它是一个很好的组件,具有一些非常有用的特性,比如multi-select、expand-all/collapse-all。 我在他们的任何api中都找不到任何树过滤特性。 有没有人发现这个功能或做了任何工作来获得mat-tree过滤器?

    enter image description here

    4 回复  |  直到 7 年前
        1
  •  5
  •   georg-un Amit Chigadani    7 年前

    我通过创建一个新的数据源(过滤)解决了这个问题。

    stackblitz sample

    我将解释共享链接的示例:我使用 filter(filterText: string) 在里面 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);
    }
    
        2
  •  4
  •   georg-un Amit Chigadani    7 年前

    在我花了几天时间完成同一项任务之后,我可以给你一些建议: 我正在使用输入事件跟踪用户输入:

    <input matInput class="form-control" 
      (input)="filterChanged($event.target.value)" 
      placeholder="Search Skill">
    

    在这个过滤器上,我附加了一个主题以便可以订阅它:

    searchFilter: Subject<string> = new Subject<string>();
    filterChanged(filter: string): void {
      this.searchFilter.next(filter);
    }
    

    通常,为了让用户能够顺利地进行搜索,我们希望延迟您可以使用的搜索执行 debounceTime .

    this.searchFilter.pipe(debounceTime(500), distinctUntilChanged())
      .subscribe(value => {
        if (value && value.length >= 3) {
          this.filterByName(value);
        } else {
          this.clearFilter();
        }
    });
    

    为了执行搜索,我使用css类隐藏和显示节点。这是直接在表示集上完成的,表示集是平坦的,并且非常容易过滤。

    treeControl: FlatTreeControl<SkillFlatNode>;
    this.treeControl.dataNodes
    

    首先,我隐藏所有内容,然后只显示符合条件的内容。最后,我想展示他们的父母,但这是我的树结构具体。

    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);
      });
    }
    

    最后,这里是clear过滤器:

    private clearFilter(): void {
      this.treeControl.dataNodes.forEach(x => x.visible = true);
    }
    

    不要像我一样犯同样的错误,试着过滤输入集合( 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;
    });
    
        3
  •  1
  •   Karthik    7 年前

    我可以使用简单的递归来过滤树。下面是代码片段:

    这个 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();
      }
    

    树结构由接口定义

    export interface ITreeDataStructure {
        Id?: number;
        name: string;
        type: string;
        children?: Array<ITreeDataStructure>;
    }
    

    实际的过滤是由函数完成的 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;
      }
    
        4
  •  0
  •   CertainPerformance    8 年前

    首先在视图中添加一个输入作为过滤器。将keyup事件绑定到rxjs主题

    <input type="text" matInput placeholder="search" #filter (keyup)="keyEvent.next($event)" [(ngModel)]="keyword">
    

    然后查询后端以使用关键字筛选树节点

    this.keyEvent.pipe(
      map((e: any) => e.target.value.toLowerCase()),
      debounceTime(500),
      distinctUntilChanged(),
      switchMap((keyword: string) => {
        if (keyword && keyword.length > 2) {
          return this.yourservice.searchForData(this.entId, keyword);
        } else {
          return of();
        }
      })
    )
    .subscribe((r) => {
      this.nestedDataSource.data = r;
      this.nestedTreeControl.dataNodes = r;
      this.nestedTreeControl.expandAll();
    });