我试图了解从api存储(和更新)数据的最佳方法,并在兄弟组件之间共享这些数据。这就是我试过的。
拯救可观测的
export class MyExampleService {
private data: Observable<any>;
constructor(private readonly http: HttpClient) { }
getData(): Observable<string[]> {
//if we already got the data, just return that
if (data) {
return data;
}
//if not, get the data
return this.http.get<string[]>('http://my-api.com/get-stuff')
.pipe(tap((returnedData: string[]) => {
//save the returned data so we can re-use it later without making more HTTP calls
this.data= returnedData;
}));
}
}但是这种方法并不完全符合我的需要,因为它不使用任何主题,当数据发生变化时,我想告诉我的其他组件。
使用主题
export class MyExampleService {
private dataSbj: BehaviorSubject<any> = new BehaviorSubject(null);
readonly data$ = this.dataSbj.asObservable();
constructor(private readonly http: HttpClient) { }
getData(): Observable<string[]> {
if (dataSbj.getValue() === null) {
return this.http.get<string[]>('http://my-api.com/get-stuff')
.pipe(tap((returnedData: string[]) => {
//save the returned data so we can re-use it later without making more HTTP calls
this.dataSbj.next(returnedData);
}));
}
}
}然后,我只需第一次订阅getData,并订阅所有其他组件中可观察到的数据$。(在本例中,我有一个父组件和多个子路由,因此我将在父组件中订阅getData(),并在所有子路由中订阅数据$)。
最后一种方法可以工作,但我宁愿使用相同的函数来检索相同的数据,而不是订阅不同的可观测值。
这是一个很好的方法,还是有什么更好的方法我可以做呢?
发布于 2020-08-12 10:31:06
如果您的getData()方法没有参数,您应该能够使用shareReplay()运算符执行以下操作。它只在第一个使用者订阅API时调用API,并将最后一个发出返回到任何顺序调用。这还包括更新数据的一种方法:
@Injectable({
providedIn: 'root'
})
export class ExampleService {
private updateData$ = new BehaviorSubject<void>(void 0);
readonly data$ = this.updateData$.pipe(
switchMap(() => this.http.get('https://reqres.in/api/users')),
shareReplay(1)
);
constructor(private readonly http: HttpClient) {}
refresh(): void {
this.updateData$.next();
}
}export class ExampleComponent {
data$: Observable<any>;
constructor(private example: ExampleService) {}
getApi(): void {
this.data$ = this.example.data$;
}
refresh(): void {
this.example.refresh();
}
}工作实例检查控制台日志
https://stackoverflow.com/questions/63374542
复制相似问题