Как отфильтровать компонент матового дерева Angular Material 6.0.1 - PullRequest
0 голосов
/ 30 мая 2018

Я использую материал углового материала матового дерева.Это хороший компонент с некоторыми очень полезными функциями, такими как, мульти-выбор, развернуть все / свернуть все.Я не смог найти ни одной функции фильтрации дерева ни в одном из их API.Кто-нибудь сталкивался с этой функцией или проделал какую-то работу, чтобы получить фильтр мат-дерева?

enter image description here

Ответы [ 4 ]

0 голосов
/ 16 января 2019

Я могу отфильтровать дерево с помощью простой рекурсии.Ниже приведены фрагменты кода:

Функция 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;
  }
0 голосов
/ 24 августа 2018

После того, как я потратил несколько дней на одну и ту же задачу, вот несколько советов, которые я могу дать: Я использую событие ввода, чтобы следить за вводом пользователя:

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

Наконец, вот прозрачный фильтр:

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;
});
0 голосов
/ 06 сентября 2018

Я решил проблему, создав новый источник данных (отфильтрованный).

образец стекаблиц

Я объясню пример общей ссылки: я отфильтровал данные с помощью 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);
}
0 голосов
/ 06 июля 2018

Сначала добавьте вход в качестве фильтра в представлении.Привязать событие 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();
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...