2

我在我的 Angular 8 项目中有一个 observable,并订阅了 ngOnInit()。

     export class ChartComponent implements OnInit {
       urlSubject: Subject<string> = new Subject();
       isLoading: BehaviorSubject<boolean> = new BehaviorSubject(false);
       chartData: BehaviorSubject<any[]> = new BehaviorSubject<any[]>([]);
       dataSubscription: Subscription;

       dataObservable: Observable<any> = this.urlSubject.pipe(
         switchMap((url: any) => this.httpClient.get<any[]>(url))
       )

       ngOnInit() {
         this.dataSubscription = this.dataObservable
          .pipe(tap(() => this.isLoading.next(true)))          
          .pipe(map((response: any) => response.result))      
          .subscribe((response: any) => this.chartData.next(response),
            () => this.isLoading.next(false),
            () => this.isLoading.next(false));

         this.urlSubject.next(this.data.settings.dataEndpoint)
      }
}

但是 complate 方法不会触发订阅。

我订阅的chartData类型是BehaviourSubject. 所以我不订阅urlSubject。因为 url 可能随时更改搜索或过滤参数。

我正在使用finilize,但它不起作用。我认为这个问题与 switchmap 内部孔隙有关。如何完成并将加载设置为 false?

4

2 回答 2

6

您需要finalizehttpClient.get. Subject 和 BehaviorSubject 在您通过调用手动完成之前不会完成subject.complete()。但是,在发出 api 响应后完成创建的 Observable httpClient,您需要使用它。

对于您的示例:

dataObservable: Observable<any> = this.urlSubject.pipe(
  tap(() => this.isLoading.next(true)),
  switchMap((url: any) =>
    this.httpClient.get<any[]>(url).pipe(
      finalize(() => this.isLoading.next(false))
    )
  )
)
于 2020-04-14T22:47:15.103 回答
0

如上所述,主题永远不会完成,除非您调用 subject.complete();

话虽如此,主题是可观察的,您始终可以使用take(COUNT)takeUntil运算符等取消订阅它们。

于 2020-04-14T08:34:16.457 回答