Angular Rxjs如何在智能组件中等待来自动态组件的所有观察结果完成
嗨 在我的项目中,我想通过点击页面上的按钮进行导出(PDF)。在我的页面中,我有一个动态创建多个图表的仪表板。当我单击“导出”按钮时,我想通知每个动态组件从当前图表实例创建一个svg,并将其传递给“页面”组件。为了能够创建svg,我必须等待图表的实例被创建。当我拥有来自不同动态组件的所有svg时,我能够将信息(不同的svg)传递到api调用主体,该api调用将创建pdf 所以我试着用一种简单的方式来实现这一点。我不知道正确的方法,所以我尝试用动态组件中的可观察值填充服务中的数组Angular Rxjs如何在智能组件中等待来自动态组件的所有观察结果完成,angular,highcharts,rxjs,Angular,Highcharts,Rxjs,嗨 在我的项目中,我想通过点击页面上的按钮进行导出(PDF)。在我的页面中,我有一个动态创建多个图表的仪表板。当我单击“导出”按钮时,我想通知每个动态组件从当前图表实例创建一个svg,并将其传递给“页面”组件。为了能够创建svg,我必须等待图表的实例被创建。当我拥有来自不同动态组件的所有svg时,我能够将信息(不同的svg)传递到api调用主体,该api调用将创建pdf 所以我试着用一种简单的方式来实现这一点。我不知道正确的方法,所以我尝试用动态组件中的可观察值填充服务中的数组 我遇到的问题是,
我遇到的问题是,在登录页组件中执行forkjoin之前,如何知道来自动态组件的所有可观察对象(在失败时返回SVG或错误)都已添加到数组中。我的forkJoin也不返回svg,所以我做错了什么。但也许有更好的方法等待所有动态组件创建它们的svg。像您这样使用服务的方法是一种方法 另一种解决方案可能是从动态组件导出
public
函数,然后从父组件调用它们
例如,我有一个模拟svg导出的简单的ChartComponent
:
@组件({
选择器:“应用程序图表”,
templateUrl:“./chart.component.html”,
样式URL:[“/chart.component.css”]
})
导出类图表组件{
exportSvg():可观察{
返回延迟(()=>
计时器(Math.random()*2000+500).pipe(映射到('svg'))
)
}
}
现在,在我的父组件中,我查询这些组件并根据需要调用exportSvg
:
@组件({
选择器:“我的应用程序”,
templateUrl:“./app.component.html”,
样式URL:[“/app.component.css”]
})
导出类AppComponent{
@ViewChildren(ChartComponent)图表:QueryList;
onExportClick():无效{
const charts=this.charts.map(component=>component.exportSvg());
forkJoin(charts.subscribe(console.log)
}
}
在我的示例中,我没有动态创建ChartComponent
s,但它的行为应该是相同的
完整的例子可以在中找到,我认为问题在于当
chartInstanceStream$
发出时,它没有订户,这意味着它无法完成,因为first()
chartInstanceStream$
由于在testService之前发生的setChartInstance
而发出。单击ExportPDFStream
发出
一个快速修复方法是将chartInstanceStream
转换为ReplaySubject
,以便将其最新值重播给迟到的订阅者
因此,从这里:
chartInstanceStream$=新主题();
为此:
chartInstanceStream$=新的ReplaySubject(1);
forkJoin
内部订阅所有提供的可观察对象。通过将chartInstanceStream$
转换为ReplaySubject
,您可以确保延迟订户(来自forkJoin
的订户)将收到由ReplaySubject
发出的最早值
因为你的可观察物,它forkJoin
订阅如下:
this.chartInstanceStream$.pipe(
地图((图表:Highcharts.chart)=>
chart.getSVG()
),
首先()/!
)
在它们发出一个值后,它们也将立即完成,因为first()
您的所有动态组件都订阅了clickExportPdfStream
事件,该事件被同步调用,因此它们都将位于该数组中此问题(及其答案)如果正在检查的代码在这个站点上而不是隐藏在另一个站点上会更好。。。