【问题标题】:Angular 4 routes are calling ngOnInit every time component is loaded repeating API call每次加载组件时,Angular 4 路由都会调用 ngOnInit,重复 API 调用
【发布时间】:2019-07-21 20:22:06
【问题描述】:

我有一个小网络应用程序,它基本上列出了一个播放器列表,当用户点击播放器名称时,它会显示播放器详细信息。它使用两个 api 调用,一个用于列表,另一个用于加载所选播放器的详细信息。我的问题是,当我从详细信息路由返回主路由时,组件再次执行 ngOnInit,因此它再次进行第一次 api 调用以再次加载主列表,我不想再次调用此调用。这是我的配置:

routing.module.ts

...
export const routes: Routes = [
  {
    path: '',
    component: BioStatsComponent,
    resolve: {
      biostats: BiostatsResolverService
    }
  },
  {
    path: 'info',
    children: [
      {
        path: ':id',
        component: InfoComponent,
        resolve: {
          info: PlayersResolverService
        }
      }
    ]
  }
];
...

detail.component.ts

ngOnInit(){
...
this.playersinfo = this.route.snapshot.data['info'];
...
}

home.component.ts

ngOnInit(){
...
this.biostats$ = this.route.snapshot.data['biostats'];
...
}

detail-resolver.service.ts

...
resolve(route: ActivatedRouteSnapshot, rstate: RouterStateSnapshot): Observable<any> {
    const id = route.paramMap.get('id');
    return this.playerService.getPlayerCommonInfo(+id).catch((err: any) => of([err]));
  }
...

home-resolver.service.ts

constructor(private playerService: PlayersService) {}
  resolve(route: ActivatedRouteSnapshot, rstate: RouterStateSnapshot): Observable<any> {
    return this.playerService.getPlayerBioStats();
  }

【问题讨论】:

    标签: angular routing resolver


    【解决方案1】:

    您应该使用服务。调用一次 api 并将其保存在变量中,例如服务中的 playerListData。现在,当您返回列表路由时,请检查该服务中的数据是否为空。假设它不为null,您不调用api并直接使用playerListData。如果它为空,那么您可能是第一次访问列表路由。在这种情况下调用 API。这样,当服务中的数据为空时,您的 api 只会被调用一次。

    我提供了一个松散的实现方式。

    ngOnInit() {
     if(this.service.playerListData!=null)
      {
        this.listData = this.service.playerListData;
      }
     else {
        this.listData =  callTheAPI();
    }
    

    在服务内部,您将有类似的代码,

    this.playerListData = null;
    callTheAPI(){
     code to call the api and get the data.
     this.playerListData = dataFromAPI;
    }
    

    【讨论】:

    • 这真的是最好的方法吗?我认为这可能是角度考虑不使用变量来做的事情。我所掌握的所有信息都是人们问相反的问题,他们每次都想调用 ngOnInit,所以我认为是我做错了。
    • 看看路由是如何在角度工作的,每次它登陆一个路由时,如果你来自不同的路由,它会重新加载组件。因此,当组件被加载时(在来自您的详细信息组件之后),自然会再次调用 ngOnInit()。因此,在调用 api 的 ngOnInit() 中放置一个方法将被再次调用。你的流程是什么?你认为这可以由你或 Angular 完成吗?
    • 好的,好的,我明白了,我以为我改变的是路径而不是路径,现在我明白路径就是路径。我读到当路由更改时调用 ngOnInit 但我认为这不是我的情况。我看到具有类似配置的人使用状态避免在返回加载的组件时加载 ngOnInit,这让我感到困惑。
    【解决方案2】:

    “每次加载组件时,Angular 4 路由都会调用 ngOnInit,重复 API 调用”这就是 Angular 处理其组件的方式。 我不明白将 API 响应保存在变量中并在重新访问后重用它有什么意义,我认为如果您下次这样做,您可能会错过该播放器列表中的新更新。

    【讨论】:

    • 如果要接收的数据非常庞大,保存并重复使用它是有意义的。正如您正确地说的那样,可能会错过更新。同样,从 API 获取的数据大小是多少?前端是更新数据库中数据的唯一方式吗?数据是只读的,没有更新吗?因此可以选择一种策略。
    • 是的,你是对的@emkay,在我的情况下,这个数据库需要 3 秒才能加载,它是一个固定的数据库,所以为什么每次我从用户详细信息返回时都需要花费这么多时间?这是我的观点。
    • 好的,在这种情况下,您可以使用该数据的 XML 文件,您不需要数据库中的任何表来存储该数据或 API 调用。
    猜你喜欢
    • 2017-12-27
    • 1970-01-01
    • 2018-06-13
    • 2018-08-08
    • 2023-03-30
    • 2017-10-04
    • 2020-06-13
    • 2017-11-05
    • 2017-12-03
    相关资源
    最近更新 更多