角树结构,其中包含来自嵌套rxjs订阅的2个不同列表

时间:2019-05-30 14:14:50

标签: angular tree rxjs material

在Angular 7中,我有两个可观察到的东西,它们是从服务器获取数据的。 Observables给出以下列表:

    productgroup = [{"id":"1","groupname":"gr1"},{"id":"2","groupname":"gr2"}];
    products = [{"id":"1","productname":"COMPUTER","productgroup":"gr2",....},{"id":"2","productname":"ACCESSORIES","productgroup":"gr1",....}]

我必须创建一个树数据结构来创建一个带有角材料树的菜单,如下所示:

    [
        {
            "id":1,
            "name": "gr1",
            "children": [
                {"id":"1","productname":"COMPUTER","productgroup":"gr2",....},
                {"id":"2","productname":"ACCESSORIES","productgroup":"gr1",....}
            ]
        }
        {
        }
    ]

我尝试过的代码如下-

 this.productGroupService.getAll().pipe(switchMap((allgroup: any) => {
          var flag = 0;
          this.groups = []; // array to hold group or parent data
          allgroup.map(element => {
            this.finalarr = []; // fial array 
            console.log(element.id);

            this.productService.getbygroup(element.id)// for each group getting product data list
            .pipe(map((data) => {
              this.productInGroup[flag] = []; // array to hold children data
              this.groups.push(element);
              data.map((dval)=>{
                this.productInGroup[flag].push({productname: dval["productname"], id: String(dval["id"])});
              })
              flag++;

            })
            ).subscribe((data) => {
              if(allgroup.length == flag){
                //console.log(this.groups);
                var flag2 = 0;
                this.groups.map(()=>{
                  var obj = {groupname: this.groups[flag2].groupname,id:this.groups[flag2].id,
                    products:this.productInGroup[flag2]}; // joining child and parent data into single object
                  this.finalarr.push(obj);
                  flag2++;
                  if(flag2 == this.groups.length){
                    this.datasource = this.finalarr;
                    console.log(this.datasource);
                  }
                })
              }
            })
          });
      })).subscribe()

首先,我遍历产品组列表并创建一个父数组。 然后,对于每个组,我通过订阅从服务器获取数据并创建一个子数组。然后使用该数组制作对象并将其推到最终数组。

该代码适用于小型数据集。但是我对此解决方案不满意 因为它遍历所有产品nxm次所有组。

我知道,如果数据库中的表通过外键和平面列表关联起来会容易得多,但我对此无能为力。

任何帮助或建议都适用。谢谢!

1 个答案:

答案 0 :(得分:1)

通过介绍状态,您的解决方案变得非常复杂。

尝试一下

  const productGroup$ = this.productGroupService.getAll();

  productGroup$.pipe(
  mergeMap((productGroupArray) => from(productGroupArray)),
  concatMap(
    (productGroupItem) => this.productService.getbygroup(productGroupItem.id).pipe(
    map((product) => {
      let json = {};
      json['id'] = productGroupItem.id;
      json['name'] = productGroupItem.groupname;
      json['children'] = product;
      return json;
    })
  )),
  toArray()
).subscribe((val) => console.log(val));

在内部订阅中,您将直接获得数组。