Angular 如何跟踪数据是否以完全反应的方式加载?

Angular 如何跟踪数据是否以完全反应的方式加载?,angular,rxjs,Angular,Rxjs,考虑以下代码 英雄:可观察; private\u loadHeroes:EventEmitter=新的EventEmmiter; 构造函数(heroService:heroService){ this.heroses=\u loadheroses.switchMap(()=>heroService.fetchheroses()); } 有没有人知道如何在不进行手动订阅的情况下,以适当的反应方式添加类似于heroesLoaded:Behavior Subject的内容? 当然我可以做类似的事情

考虑以下代码

英雄:可观察;
private\u loadHeroes:EventEmitter=新的EventEmmiter;
构造函数(heroService:heroService){
this.heroses=\u loadheroses.switchMap(()=>heroService.fetchheroses());
}
有没有人知道如何在不进行手动订阅的情况下,以适当的反应方式添加类似于
heroesLoaded:Behavior Subject
的内容? 当然我可以做类似的事情

this.heroes=\u loadHeroes.switchMap(()=>{
this.heroesLoaded.next(false)
heroService.fetchHeroes().finally(()=>this.heroesLoaded.next(true)
});

但我认为这并不是最好的方法,我的想法是将所有订阅都保留在异步管道中,并且只在流中执行所有操作。此外,我不想像上面所描述的那样使用不纯净的副作用来编写它。我试着寻找pulishBehavior操作符,但我不知道如何使用它对订阅时刻和当前时刻做出反应有价值的匹配/错误。有可能吗?我对任何可能的解决方案感兴趣,这些解决方案至少更好,但不一定完美。

如果您只想跟踪它们是否已加载(例如,显示加载指示器):

英雄:可观察;
heroesLoaded:boolean=false;
构造函数(heroService:heroService){
this.heroesLoaded=false;
this.heros=of(null).pipe(
点击(()=>this.heroesLoaded=false),
flatMap(()=>heroService.fetchHeroes()),
完成(()=>this.heroesLoaded=true)
);
}

如果需要,可以将heroesLoaded设置为BehaviorSubject,并将行
this.heroesLoaded=false
替换为
this.heroesLoaded.next(false)
-我不知道这会带来什么好处,但使用点击和定稿的原则是一样的。

通过调用
this.heroesLoaded.next
如果您担心这一点,您不会创建新订阅。我知道我不知道,但这不是真正正确的方法,是吗?我们不应该在地图功能中产生副作用在
*map
操作符中使用nSide效果确实不是一个好主意,但是您可以使用
轻触
完成
操作符来实现这些功能(如果您使用这种方法).我知道,但在我的示例中,我没有使用http请求的直接可观察性,但它是另一个可观察的,在这种情况下,tap、finilize的副作用将在switchMap中,或者这样就可以了?@Blind绝望不,它们可以像我展示的示例中那样处于顶级。两者都可以工作,但没有必要嵌套它们。我知道这一点这样做的方法,只是希望有更好的方法。另一种方法可以简单地以
of(null)
开始可观察的,然后
concatMap
heroService.fetchheros()
。这将导致整个链的输出首先为null,然后是加载的数据,您可以在模板中对此做出反应(例如,
然后有一个#加载模板)@BlindDespair@BlindDespairnull是类型
Hero[]
的有效值,因此我不认为您需要更改类型。尽管您需要执行null检查,但您是正确的。
heroes: Obserable<Hero[]>;
heroesLoaded: boolean = false;

constructor(heroService: HeroService) {
   this.heroesLoaded = false;
   this.heroes = of(null).pipe(
       tap(() => this.heroesLoaded = false),
       flatMap(() => heroService.fetchHeroes()),
       finalize(() => this.heroesLoaded = true)
   );
}