减少网络通话

时间:2020-04-21 08:37:37

标签: angular http

我有2个组件UsersComponent和HelloComponent。

我在两个组件上使用相同的api调用来调用相同的服务。

但是我想要的是,如果UsersComponent正在调用api,那么HelloComponent不应该调用api,它应该从UsersComponent接收值。

当前这两个组件上都在进行网络呼叫。

有什么办法。请帮忙。

Stackblitz链接:

https://stackblitz.com/edit/angular-service-3ifvpr?file=app%2Fhello.component.ts

如果将工作演示放在stackblitz中,请多谢。

2 个答案:

答案 0 :(得分:0)

我认为您应该像这样在服务中使用自制缓存,并在两个组件中同时使用服务(认为这是最好的做法)

// Map of your posts <idPost, Post>
private posts: Map<number, any>;

getPosts(): Observable<any[]> {

    let data: Observable<any[]>;

    if (this.posts) {
      data = defer(() => Promise.resolve(Array.from(this.posts.values())));
    } else {
      data = this.http.get('https://jsonplaceholder.typicode.com/posts').pipe(
        map(results => {
          this.posts= new Map();
          results.forEach(post => {
            this.posts.set(post.id, post);
          });
          return results;
        })
      );
    }

    return data ;
}

答案 1 :(得分:0)

作为一个简单的解决方案,您可以创建一个Resolver来加载和缓存数据。解析程序在创建组件之前先加载数据,因此您将在组件构造函数中加载所有数据。这是解析器的示例:

// data.resolver.ts

export interface DataResolverData {
  data: any;
  error?: Error;
}

@Injectable()
export class DataResolver implements Resolve<DataResolverData> {
  private data?: any;

  constructor(
    private readonly appService: AppService
  ) {}

  resolve(
    route: ActivatedRouteSnapshot
  ): Observable<DataResolverData> {
    if (this.data) {
      return of({
        data: this.data
      });
    } else {
      return this.appService.getData().pipe(
        catchError(err => of({
          error: err
        })),
        tap(response => {
          this.data = response;
        }),
        map(response => ({
          data: response
        }))
      );
    }
  }
}

// app.module.ts

const appRoutes: Routes = [
  // note that I've added the same resolver for both routes
  { path: 'hello', component: HelloComponent, resolve: {data: DataResolver} },
  { path: 'users', component: UsersComponent, resolve: {data: DataResolver} }
];

...

@NgModule({
  ...
  providers:    [ AppService, DataResolver ]
})
export class AppModule {}

// hello.component.ts

export class HelloComponent  {
  constructor(private route: ActivatedRoute) {
    const { data, error } = this.route.snapshot.data.data as DataResolverData;
    console.log('hello', data, error);
  }
}

StackBlitz

实际上,您可以在服务中存储和缓存数据,这些数据将被多个解析器或组件重用。这取决于应用程序的上下文和要求。

另一个解决方案可能是使用NgRxNGXS之类的商店。商店是一个涉及更多的解决方案,并不适合每个项目,这里good article是有关在角度应用程序中使用商店解决方案的优缺点的{{3}}。我刚刚提到它是因为它与问题有关。