Дерево: Как сохранить открытые состояния при обновлении дерева - PullRequest
0 голосов
/ 13 ноября 2018

Мне нужно указывать открытые / закрытые узлы дерева, когда я устанавливаю новые данные в this.dataSource.data.Новые данные очень похожи со старыми - просто добавляется / удаляется один или несколько узлов самого низкого уровня.

Моя идея - записать расширение узла до ReplaySubject и воспроизвести очередь расширения.Это должно работать, но это очень уродливо.

Я надеюсь, что здесь есть гораздо более элегантный способ решить мою проблему.

1 Ответ

0 голосов
/ 13 ноября 2018

Я добавил логическое «расширенное» в мою модель данных. Затем я использую функцию (щелчок), которая инвертирует это, и рекурсивный цикл, чтобы сохранить это изменение в фактических данных, которые используются для dataSource.data. Так что на самом деле я больше не использую древовидный контроль, хотя он мне все еще нужен (дерево не работает без него).

    <button mat-icon-button
    [attr.aria-label]="'toggle ' + node.name"
    (click)="changeState(node, myJson)"
    >
      <mat-icon class="mat-icon-rtl-mirror">
        {{node.expanded ? 'expand_more' : 'chevron_right'}}
      </mat-icon>
    </button>

-

  /** Changes expanded state for clicked tree-item, saves change to json data used by tree datasource */
  changeState(node, myJson) {
    node.expanded = !node.expanded;

    if (node.children && node.children.length > 0) {
      this.found = false;
      myJson.forEach(child => {
        if (!this.found) {
        this.saveStates(child, node);
        }
      });
    }
  }

  /** recursive loop-function used by this.changeState() to save tree-items expanded-state to the master array */
  saveStates(child, clickedChild) {
    if (child.id === clickedChild.id) {
      child.expanded = clickedChild.expanded;
      this.found = true;
      return;
    } else if (child.children && child.children.length > 0) {
      child.children.forEach(c => {
        this.saveStates(c, clickedGroup);
      });
    }
  }

- И стандартные функции из дерева-примера, которые я изменил, чтобы работать с моими данными:

  // checks if datasource for material tree has any children
  hasNestedChild = (_: number, nodeData: MyModel) => nodeData.children.length > 0;

  // returns children
  private _getChildren = (node: MyModel) => node.children;
...