使用 rxjs 管理 API 数据响应并管理应用程序状态 - Angular 10
Manage API data reponse with rxjs and manage application state - Angular 10
我正在尝试了解从 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 并订阅所有其他组件中可观察到的 data$。 (在这种情况下,我有一个父组件和多个子路由,所以我会在父组件中订阅 getData() 并在所有子路由中订阅 data$)。
最后一种方法可行,但我宁愿使用相同的函数来检索相同的数据,而不是通过订阅不同的可观察对象。
这是一个好的方法还是我可以做一些更好的事情?
如果您的 getData()
方法没有参数,您应该能够使用 shareReplay()
运算符执行以下操作。它只会在第一个消费者订阅它时调用 API,并且将 return 最后一个发送到任何顺序调用。这还包括一种更新数据的方法:
@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();
}
}
working example检查控制台日志
NGRX store 状态管理是一种在数据可用时从存储中读取的方法,而不是进行不必要的网络调用。
它通过调度相关操作负责创建、更新和删除存储中的记录。
这里是关于 github 如何使用 ngrx 存储的完整源代码 DEMO。
我强烈建议使用 ngrx store,它有一些很酷的功能可以避免不必要的网络调用,这会导致您的应用程序加速。
我正在尝试了解从 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 并订阅所有其他组件中可观察到的 data$。 (在这种情况下,我有一个父组件和多个子路由,所以我会在父组件中订阅 getData() 并在所有子路由中订阅 data$)。
最后一种方法可行,但我宁愿使用相同的函数来检索相同的数据,而不是通过订阅不同的可观察对象。
这是一个好的方法还是我可以做一些更好的事情?
如果您的 getData()
方法没有参数,您应该能够使用 shareReplay()
运算符执行以下操作。它只会在第一个消费者订阅它时调用 API,并且将 return 最后一个发送到任何顺序调用。这还包括一种更新数据的方法:
@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();
}
}
working example检查控制台日志
NGRX store 状态管理是一种在数据可用时从存储中读取的方法,而不是进行不必要的网络调用。
它通过调度相关操作负责创建、更新和删除存储中的记录。
这里是关于 github 如何使用 ngrx 存储的完整源代码 DEMO。
我强烈建议使用 ngrx store,它有一些很酷的功能可以避免不必要的网络调用,这会导致您的应用程序加速。