Angular 4 组件 ngOnInit 未在每个路由请求上调用 [英] Angular 4 Component ngOnInit not called on each route request

查看:22
本文介绍了Angular 4 组件 ngOnInit 未在每个路由请求上调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近才开始从 Angular 1.5 开始深入研究 Angular 4.我正在处理用户路由并将 API 数据从服务中提取到用户组件中.

I just recently started diving into Angular 4 coming from Angular 1.5. I'm working with user routes and pulling API data from a service into a user component.

与 1.* 中的控制器不同,该组件似乎保持静态,每次请求都会刷新.

The component seems to stay static unlike controllers in 1.* where they were refreshed on each request.

无论如何都要在每个新的路由请求上调用 ngOnInit 函数吗?

Is there anyway to have the ngOnInit function called on each new route request?

我的用户组件类:

// url structure: /user/:id
export class UserComponent implements OnInit {

    constructor(private route: ActivatedRoute) {}

    ngOnInit() {

      // doesn't log new id on route change
      let id = this.route.snapshot.params['id'];
      console.log(id);

      this.route.params
        .switchMap(params => this.userService.getUser(params['id']))
        .subscribe(user => {
          // logs new id on route change
          let id = this.route.snapshot.params['id'];
          console.log(id);

          this.user = user
        });
    }
}

更新:

找到了一个我认为最适合我的场景的解决方案.根据对我的问题和进一步调查的几个答案和评论,订阅该路线似乎是要走的路.这是我更新的组件:

Found a solution that I think works best for my scenario. Based on several answers and comments to my question and further investigation, subscribing to the route seems to be the way to go. Here is my updated component:

export class UserComponent {

  user;
  id;

  constructor(
    private userService: UserService,
    private route: ActivatedRoute
  ) {}


  ngOnInit() {
    this.route.params
      .subscribe(params => this.handleRouteChange(params));
  }

  handleRouteChange(params) {
    this.id = params['id'];

    switch (this.id) {
      case '1':
        console.log('User 1');
        break;

       case '2':
        console.log('User 2');
        break;

       case '3':
        console.log('User 3');
        break;
    }

    this.userService.getUser(this.id).
      subscribe(user => this.user = user);
  }

}

推荐答案

如果路由相同但参数发生变化,Angular 默认情况下更喜欢重用相同的组件,而不是实例化一个新组件.

Angular prefers -by default- to reuse the same component instead of instanciating a new one if the route is the same but the parameters change.

好消息!这是一个可定制的行为,您可以通过实现自己的 RouteReuseStrategy:

Good news ! this is a customizable behavior, you can force instanciating a new component instance by implementing your own RouteReuseStrategy:

export class MyRouteReuseStrategy extends DefaultRouteReuseStrategy {
  shouldReuseRoute(next: ActivatedRouteSnapshot, current: ActivatedRouteSnapshot): boolean {
    let name = next.component && (next.component as any).name;
    return super.shouldReuseRoute(next, current) && name !== 'UserComponent';
  }
}

在您的模块中:

@NgModule({
  ...
  providers:[{
      provide: RouteReuseStrategy,
      useClass: MyRouteReuseStrategy}]
  ...
})
export class AppModule {}

(此代码或多或少来自这篇文章,尤其是对 name 属性的检查,这可能不是很准确...)

(this code is more or less taken from this article, especially the check for the name property which might not be very accurate...)

请注意,重新实例化相同组件时可能会出现一些性能缺陷.所以也许你最好使用 observables 属性而不是快照.

Note that ther might be some performance drawback when reinstanciating the same component. So maybe you'd better use the observables properties instead of the snapshot.

这篇关于Angular 4 组件 ngOnInit 未在每个路由请求上调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆