Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/375.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 管理Angular服务和组件之间的订阅_Javascript_Angular_Typescript_Angularfire - Fatal编程技术网

Javascript 管理Angular服务和组件之间的订阅

Javascript 管理Angular服务和组件之间的订阅,javascript,angular,typescript,angularfire,Javascript,Angular,Typescript,Angularfire,我正在开发一个web应用程序,其中多个组件共享类似的功能。为了避免不同组件中的代码重复,我创建了一个服务来承载这些功能 但是,我不确定如何管理共享功能的订阅,因为它们不再是每个组件的一部分,仍然需要在服务中订阅。理想情况下,我不会在服务中订阅,而只在组件中订阅,但函数的性质及其用途不允许我这样做。这些是相互嵌套的AngularFire函数。此结构的目的是浏览数据库的不同级别并动态填充对象。然后使用此对象生成主表的headers部分。级别(列和堆叠行)的数量取决于数据库中存在的数据,具体取决于所查

我正在开发一个web应用程序,其中多个组件共享类似的功能。为了避免不同组件中的代码重复,我创建了一个服务来承载这些功能

但是,我不确定如何管理共享功能的订阅,因为它们不再是每个组件的一部分,仍然需要在服务中订阅。理想情况下,我不会在服务中订阅,而只在组件中订阅,但函数的性质及其用途不允许我这样做。这些是相互嵌套的AngularFire函数。此结构的目的是浏览数据库的不同级别并动态填充对象。然后使用此对象生成主表的headers部分。级别(列和堆叠行)的数量取决于数据库中存在的数据,具体取决于所查询的数据库节点。这不是我最喜欢的处理方法,所以如果你想一个更干净的方法来做这件事,无论如何。请记住,实际代码比下面的示例要复杂一些

例如,以下对象由该代码生成,其对应的标题部分显示在下图中:

object = {

    title: 'PW100',
    sections: {
      section1: {
        title: 'HIGH PRESSURE ROTOR',
        sections: {
          section1: {
            title: 'HP TURBINE',
            sections : {
              section1: {title: 'ASS'},
              section2: {title: 'GRD'},
              section3: {title: 'BAL'}
            }
          },
          section2: {
            title: 'HP ROTOR',
            sections: {
              section1: {title: 'ASS'},
              section2: {title: 'BAL'}
            }
          }
        }
      },
      section2: {
        title: 'LOW PRESSURE ROTOR',
        sections: {
          section1: {
            title: 'LP TURBINE',
            sections : {
              section1: {title: 'ASS'},
              section2: {title: 'RIV'},
              section3: {title: 'GRD'},
              section4: {title: 'BAL'}
            }
          },
          section2: {
            title: 'LP ROTOR',
            sections: {
              section1: {title: 'ASS'},
              section2: {title: 'BAL'}
            }
          }
        }
      },
      section3: {
        title: 'POWER TURBINE PACK',
        sections: {
          section1: {
            title: '3RD STAGE TURBINE',
            sections : {
              section1: {title: 'ASS'},
              section2: {title: 'RIV'},
              section3: {title: 'GRD'},
              section4: {title: 'BAL'}
            }
          },
          section2: {
            title: '4TH STAGE TURBINE',
            sections : {
              section1: {title: 'ASS'},
              section2: {title: 'RIV'},
              section3: {title: 'GRD'},
              section4: {title: 'BAL'}
            }
          },
          section3: {
            title: 'PT PACK',
            sections: {
              section1: {title: 'ASS'},
              section2: {title: 'BAL'}
            }
          }
        }
      }
    }

  };

在那之前我所拥有的一切都很完美: 组件A和B过去具有以下结构:

导出类ComponentXXClass实现OnInit、OnDestroy{
//用于在Ngondestory()中取消订阅的变量
$unsubscribe=新主题();
构造函数(专用afs:AngularFirestore){}
ngOnInit():void{
this.function().then(结果=>{
//使用promise的结果(这是一个对象)生成表的标题部分
});
}
ngOnDestroy():void{
此。$unsubscribe.next();
这是。$unsubscribe.complete();
}
函数(){
const objecttopopulateonechlevel={};
返回新承诺((解决)=>{
this.afs.collection('collectionName')
.snapshotChanges()
.pipe(takeUntil(此$unsubscribe))
.subscribe(level1变量需要访问level2=>{
Level1VariableRequired访问Level2.forEach(level1Var=>{
//存储在此查询级别找到的相关信息
objectToPopulateOnEachLevel['level1']=level1Var.payload.doc.data()['variableOfInterest'];
此.afs.collection(level1Var.payload.doc.ref.path+'/path1')
.snapshotChanges()
.pipe(takeUntil(此$unsubscribe))
.subscribe(level2Variable=>{
level2Variable.forEach(level2Var=>{
//存储在此查询级别找到的相关信息
objectToPopulateOnEachLevel['level2']=level2Var.payload.doc.data()['variableOfInterest'];
});
解决(objectToPopulateOnEachLevel);
});
});
});
});
}
}
代码的公共部分在组件A和组件B之间重复(在我的真实场景中还有更多),因此我最终做了如下工作: 服务:

导出类服务{
//用于在组件的Ngondestory()中取消订阅的变量
$unsubscribe=新主题();
构造函数(专用afs:AngularFirestore){}
函数(父路径:字符串,子路径:字符串){
const objecttopopulateonechlevel={};
返回新承诺((解决)=>{
此.afs.collection(父路径)
.snapshotChanges()
.pipe(takeUntil(此$unsubscribe))
.subscribe(level1变量需要访问level2=>{
Level1VariableRequired访问Level2.forEach(level1Var=>{
//存储在此查询级别找到的相关信息
objectToPopulateOnEachLevel['level1']=level1Var.payload.doc.data()['variableOfInterest'];
此.afs.collection(level1Var.payload.doc.ref.path+'/'+childPath)
.snapshotChanges()
.pipe(takeUntil(此$unsubscribe))
.subscribe(level2Variable=>{
level2Variable.forEach(level2Var=>{
//存储在此查询级别找到的相关信息
objectToPopulateOnEachLevel['level2']=level2Var.payload.doc.data()['variableOfInterest'];
});
解决(objectToPopulateOnEachLevel);
});
});
});
});
}
}
组件A和B:

导出类ComponentXXClass实现OnInit、OnDestroy{
构造函数(私有_服务:服务){}
ngOnInit():void{
这个._service.functo('parentPathString','childPathString')。然后(结果=>{
//使用promise的结果(这是一个对象)生成表的标题部分
});
}
ngOnDestroy():void{
此._服务.$unsubscribe.next();
此._服务.$unsubscribe.complete();
}
}
这是可行的,但并不完全可行。我的意思是数据显示正确,但似乎即使我没有退出组件A(例如),订阅似乎也没有激活。在组件A中,我尝试在服务中订阅的节点上更新DB中的变量。预期行为是使订阅触发并向组件a发出新值。例如,在上面的示例中(对象及其相应的标题显示在图像中),如果我进入DB并将“高压转子”更改为“无压力转子”,我预期订阅将在服务中触发,通过在promise中重新创建对象并将其重新发送给组件A,然后组件A将重新呈现表头来获取更改。然而,这并没有发生。我还试图删除“退订”部分,看看我处理退订的方式是否是原因。结果是一样的

有什么想法吗


谢谢

您必须使用可观测数据来管理t的状态