如何在树角中添加新节点?

开V

我将Tree 与动态数据一起使用

组件代码为:

import {CollectionViewer, SelectionChange} from '@angular/cdk/collections';
import {FlatTreeControl} from '@angular/cdk/tree';
import {Component, Injectable} from '@angular/core';
import {BehaviorSubject, merge, Observable} from 'rxjs';
import {map} from 'rxjs/operators';

/** Flat node with expandable and level information */
export class DynamicFlatNode {
  constructor(public item: string, public level = 1, public expandable = false,
              public isLoading = false) {}
}

/**
 * Database for dynamic data. When expanding a node in the tree, the data source will need to fetch
 * the descendants data from the database.
 */
export class DynamicDatabase {
  dataMap = new Map<string, string[]>([
    ['Fruits', ['Apple', 'Orange', 'Banana']],
    ['Vegetables', ['Tomato', 'Potato', 'Onion']],
    ['Apple', ['Fuji', 'Macintosh']],
    ['Onion', ['Yellow', 'White', 'Purple']]
  ]);

  rootLevelNodes: string[] = ['Fruits', 'Vegetables'];

  /** Initial data from database */
  initialData(): DynamicFlatNode[] {
    return this.rootLevelNodes.map(name => new DynamicFlatNode(name, 0, true));
  }

  getChildren(node: string): string[] | undefined {
    return this.dataMap.get(node);
  }

  isExpandable(node: string): boolean {
    return this.dataMap.has(node);
  }
}
/**
 * File database, it can build a tree structured Json object from string.
 * Each node in Json object represents a file or a directory. For a file, it has filename and type.
 * For a directory, it has filename and children (a list of files or directories).
 * The input will be a json object string, and the output is a list of `FileNode` with nested
 * structure.
 */
@Injectable()
export class DynamicDataSource {

  dataChange = new BehaviorSubject<DynamicFlatNode[]>([]);

  get data(): DynamicFlatNode[] { return this.dataChange.value; }
  set data(value: DynamicFlatNode[]) {
    this._treeControl.dataNodes = value;
    this.dataChange.next(value);
  }

  constructor(private _treeControl: FlatTreeControl<DynamicFlatNode>,
              private _database: DynamicDatabase) {}

  connect(collectionViewer: CollectionViewer): Observable<DynamicFlatNode[]> {
    this._treeControl.expansionModel.onChange.subscribe(change => {
      if ((change as SelectionChange<DynamicFlatNode>).added ||
        (change as SelectionChange<DynamicFlatNode>).removed) {
        this.handleTreeControl(change as SelectionChange<DynamicFlatNode>);
      }
    });

    return merge(collectionViewer.viewChange, this.dataChange).pipe(map(() => this.data));
  }

  /** Handle expand/collapse behaviors */
  handleTreeControl(change: SelectionChange<DynamicFlatNode>) {
    if (change.added) {
      change.added.forEach(node => this.toggleNode(node, true));
    }
    if (change.removed) {
      change.removed.slice().reverse().forEach(node => this.toggleNode(node, false));
    }
  }

  /**
   * Toggle the node, remove from display list
   */
  toggleNode(node: DynamicFlatNode, expand: boolean) {
    const children = this._database.getChildren(node.item);
    const index = this.data.indexOf(node);
    if (!children || index < 0) { // If no children, or cannot find the node, no op
      return;
    }

    node.isLoading = true;

    setTimeout(() => {
      if (expand) {
        const nodes = children.map(name =>
          new DynamicFlatNode(name, node.level + 1, this._database.isExpandable(name)));
        this.data.splice(index + 1, 0, ...nodes);
      } else {
        let count = 0;
        for (let i = index + 1; i < this.data.length
          && this.data[i].level > node.level; i++, count++) {}
        this.data.splice(index + 1, count);
      }

      // notify the change
      this.dataChange.next(this.data);
      node.isLoading = false;
    }, 1000);
  }
}

/**
 * @title Tree with dynamic data
 */
@Component({
  selector: 'tree-dynamic-example',
  templateUrl: 'tree-dynamic-example.html',
  styleUrls: ['tree-dynamic-example.css'],
  providers: [DynamicDatabase]
})
export class TreeDynamicExample {
  constructor(database: DynamicDatabase) {
    this.treeControl = new FlatTreeControl<DynamicFlatNode>(this.getLevel, this.isExpandable);
    this.dataSource = new DynamicDataSource(this.treeControl, database);

    this.dataSource.data = database.initialData();
  }

  treeControl: FlatTreeControl<DynamicFlatNode>;

  dataSource: DynamicDataSource;

  getLevel = (node: DynamicFlatNode) => node.level;

  isExpandable = (node: DynamicFlatNode) => node.expandable;

  hasChild = (_: number, _nodeData: DynamicFlatNode) => _nodeData.expandable;
}

数据源是类DynamicDatabase它是 Map 对象,具有 set/get 方法。

我试图通过 key 添加一个新的节点元素Fruits

 this.database.dataMap.set('Fruits', ['A', 'B']);

但它重写了旧值,而不是:

['Fruits', ['Apple', 'Orange', 'Banana', 'A', 'B']]

我也可以这样做:

this.dataSource.data = [new DynamicFlatNode('Papa', 0, true)];

但它的工作原理是一样的

伊戈尔_c

您可以尝试以下操作:

const updatedData = [...this.database.dataMap.get('Fruits'), 'A', 'B'];
this.database.dataMap.set('Fruits', updatedData);

但是如果可能的话,您可以将其更改为简单的 jsobject并像使用对象而不是使用对象一样使用它Map

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在AgensGraph中向节点添加新属性?

来自分类Dev

如何在C中的二叉树中插入新节点?

来自分类Dev

如何在节点值的开头使用Perl在XML中添加新的子节点

来自分类Dev

如何在现有节点内添加新节点?

来自分类Dev

D3.js-如何在此可折叠树中向文本添加新行?

来自分类Dev

如何从列表中添加树视图中的节点

来自分类Dev

如何在python中替换n元树中的节点?

来自分类Dev

如何在extJs 4.1树面板中突出显示节点

来自分类Dev

如何在二叉搜索树中查找节点

来自分类Dev

如何在R中计算树中的节点

来自分类Dev

如何在cassandra中添加退役节点?

来自分类Dev

构建二叉树时如何添加新节点

来自分类Dev

如何获取角ivh树视图中的选定节点的列表?

来自分类Dev

如何获取角ivh树视图中的选定节点的列表?

来自分类Dev

如何在reactjs的树中添加元素作为标题

来自分类Dev

如何在设备树源文件中添加注释

来自分类Dev

如何在设备树源文件中添加注释

来自分类Dev

如何在组合框中添加树json

来自分类Dev

在角树中创建第一个节点

来自分类Dev

在角树中创建第一个节点

来自分类Dev

如何在C ++中将文件路径作为节点添加到树或堆栈

来自分类Dev

如何在Linux中添加新的qdisc

来自分类Dev

如何在NopCommerce中添加新表?

来自分类Dev

如何在Spree中添加新角色?

来自分类Dev

如何在文件中添加新行

来自分类Dev

如何在admincp中添加新菜单

来自分类Dev

如何在FormattedString中添加新行

来自分类Dev

如何在Googlesheet中添加新数据

来自分类Dev

如何在HTML中添加新行?