Angular 如何访问多棵树';有棱角的物品?

Angular 如何访问多棵树';有棱角的物品?,angular,typescript,tree,angular-material,indexof,Angular,Typescript,Tree,Angular Material,Indexof,我在一个项目中使用角垫树作为表的过滤器。 我用复选框()创建了3个不同的嵌套树 我使用后端数据生成了这些树,并在前端(使用Spring和Angular 8)创建了一个服务,如下所示 现在,我想使用这个.treeControl.dataNodes.indexOf(节点)访问3个树中的每一项,但问题是dataNodes只存储最新创建的树(这里是“场景”树)。所以当我对另一棵树使用这个.treeControl.dataNodes.indexOf(node)时,它说:indexOf(node)=-1 我

我在一个项目中使用角垫树作为表的过滤器。 我用复选框()创建了3个不同的嵌套树

我使用后端数据生成了这些树,并在前端(使用Spring和Angular 8)创建了一个服务,如下所示

现在,我想使用这个.treeControl.dataNodes.indexOf(节点)访问3个树中的每一项,但问题是dataNodes只存储最新创建的树(这里是“场景”树)。所以当我对另一棵树使用这个.treeControl.dataNodes.indexOf(node)时,它说:indexOf(node)=-1

我想知道是否有办法通过索引访问所有这些树的项目。 如果可能,我还需要访问级别为0的所有项目

我共享一个stackblitz演示,它是我代码的简化版本:

导出类过滤器数据库{
[x:字符串]:任意;
dataChangeSub=新行为主体([]);
dataChangeSce=新行为主体([]);
dataChangeAlg=新行为主体([]);
subjectsTypes:SubjectType[];
情景:情景[];
算法:算法[];
get dataSub():TodoItemNode[]{返回this.dataChangeSub.value;}
get-dataSce():TodoItemNode[]{返回this.dataChangeSce.value;}
get dataAlg():TodoItemNode[]{返回this.dataChangeAlg.value;}
构造函数(私有场景服务:场景服务,私有协议服务:协议服务){
这是初始化();
}
初始化(){
//从Json对象生成树节点。结果是带有嵌套
//文件节点作为子节点。
//创建主题过滤器
此.protocolService.getSubjectTypes()文件已被删除。
订阅(响应=>{
this.subjectsTypes=响应;
让namesub:any=[];
this.subjectsTypes.forEach(elem=>{
让namesub_节点:string=elem.name;
namesub.push(namesub_节点);
});
让root_objSub:any={
"科目"分组
}
const dataSub=this.buildFileTree(root_objSub,0);
this.dataChangeSub.next(dataSub);
});
//创建PIs过滤器
this.protocolService.getAlgorithms()
.订阅(响应=>{
该算法=响应;
让namesAlg:any=[];
this.algorithms.forEach(elem=>{
让namesAlg_节点:string=elem.name;
namesAlg.push(namesAlg_节点);
});
让root_objAlg:any={
“算法”:namesAlg
}
const dataAlg=this.buildFileTree(根目录,0);
this.dataChangeAlg.next(dataAlg);
});
//创建场景过滤器
this.scenarioService.getScenarios()
.订阅(响应=>{
这个场景=响应;
让tree_Sce:any=[];//这将是一个对象数组
//收集数据数组中所有节点的描述和名称
让idSce:any=[];
让namesc:any=[];
this.scenarios.forEach(elem=>{
让idSce\u节点:number=elem.scenario\u id
推送(idSce_节点);
让namesce\u节点:string=elem.name
namesce.push(namesce_节点);
});
让root_objSce:any={
“情景”:{
“ID”:idSce,
“名称”:名称
}
};
树状体推进(根对象);
const dataSce=this.buildFileTree(根对象,0);
this.dataChangeSce.next(dataSce);
});
}
/**
*构建文件结构树。“value”是Json对象,或Json对象的子树。
*返回值是“TodoItemNode”的列表。
*/
buildFileTree(obj:{[key:string]:any},级别:number):TodoItemNode[]{
返回Object.keys(obj).reduce((累加器,键)=>{
常量值=对象[键];
const node=new TodoItemNode();
node.item=key;
if(值!=null){
如果(值的类型==='object'){
node.children=this.buildFileTree(值,级别+1);
}否则{
node.item=值;
}
}
返回累加器concat(节点);
}, []);
}
}

你能在上面创建一个演示代码吗?我不知道这是否可行,因为我使用后端数据…你可以创建一个后端响应的伪json数据。凯,我正在尝试,thanks@ShashankVivek,我用stackblitz链接编辑了这个问题。我们可以在控制台中看到,当我们从tree2(上次创建)中选择一个项目时,它工作得很好(索引为1,2或其他),但是当您在tree1上尝试相同的操作时,您的索引为-1(意味着数组不存在或不存在),您是否可以在其上创建演示代码。我不知道这是否可行,因为我使用后端数据…您可以创建后端响应的伪json数据Kay,我正在尝试,thanks@ShashankVivek,我用stackblitz链接编辑了这个问题。我们可以在控制台中看到,当我们从tree2(上次创建)中选择一个项目时,它工作正常(索引为1,2或其他),但当您在tree1上尝试相同的操作时,索引为-1(表示数组不存在或不存在)
export class FiltersDatabase {
  [x: string]: any;

  dataChangeSub = new BehaviorSubject<TodoItemNode[]>([]);
  dataChangeSce = new BehaviorSubject<TodoItemNode[]>([]);
  dataChangeAlg = new BehaviorSubject<TodoItemNode[]>([]);

  subjectsTypes : SubjectType[];
  scenarios: Scenario[];
  algorithms: Algorithm[];


  get dataSub(): TodoItemNode[] { return this.dataChangeSub.value; }
  get dataSce(): TodoItemNode[] { return this.dataChangeSce.value; }
  get dataAlg(): TodoItemNode[] { return this.dataChangeAlg.value; }

  constructor(private scenarioService : ScenarioService, private protocolService: ProtocolService) {
    this.initialize();
  }

  initialize() {
    // Build the tree nodes from Json object. The result is a list of `TodoItemNode` with nested
    //     file node as children.

    //creating the subjects filter
    this.protocolService.getSubjectTypes().
    subscribe(response => {
      this.subjectsTypes = response;

      let namesSub : any = [];

      this.subjectsTypes.forEach(elem =>{
        let namesSub_node: string = elem.name;
        namesSub.push(namesSub_node);
      });
      let root_objSub: any = {
        "Subjects" : namesSub
      }
      const dataSub = this.buildFileTree(root_objSub, 0);
      this.dataChangeSub.next(dataSub);
    });


    //creating the PIs filter
    this.protocolService.getAlgorithms()
    .subscribe(response =>{
      this.algorithms = response;

      let namesAlg : any = [];

      this.algorithms.forEach(elem =>{
        let namesAlg_node: string = elem.name;
        namesAlg.push(namesAlg_node);
      });
      let root_objAlg: any = {
        "Algorithms" : namesAlg
      }
      const dataAlg = this.buildFileTree(root_objAlg, 0);
      this.dataChangeAlg.next(dataAlg);
    });

    //creating the Scenarios filter
    this.scenarioService.getScenarios()
    .subscribe(response => {
      this.scenarios =response;

      let tree_Sce: any = []; // this will be array of objects
      // collect all the descriptions and names nodes form the data array
      let idSce: any= [];
      let namesSce:any = [];

      this.scenarios.forEach(elem => {

        let idSce_node: number = elem.scenario_id
        idSce.push(idSce_node);

        let namesSce_node: string= elem.name
        namesSce.push(namesSce_node);
      });

      let root_objSce: any = {
        "Scenarios" : {
          "ID": idSce,
          "Names" : namesSce
        }
      };
      tree_Sce.push(root_objSce);

      const dataSce = this.buildFileTree(root_objSce, 0);
      this.dataChangeSce.next(dataSce);
    });


  }

  /**
  * Build the file structure tree. The `value` is the Json object, or a sub-tree of a Json object.
  * The return value is the list of `TodoItemNode`.
  */
  buildFileTree(obj: {[key: string]: any}, level: number): TodoItemNode[] {
    return Object.keys(obj).reduce<TodoItemNode[]>((accumulator, key) => {
      const value = obj[key];
      const node = new TodoItemNode();
      node.item = key;

      if (value != null) {
        if (typeof value === 'object') {
          node.children = this.buildFileTree(value, level + 1);
        } else {
          node.item = value;
        }
      }

      return accumulator.concat(node);
    }, []);
  }
}