使用路由解析器将静态数据传递到Angular 8中的路由组件是一种好习惯吗?

时间:2019-11-26 21:01:18

标签: angular angular-routing angular-router angular-resolver

我们有一个User组件,它以@input的形式接收用户对象:

export class UserComponent implements OnInit {
  @Input() user: User;

  constructor() {}
}

以下是相应的模板:

<div class="user-box">
  <img class="avatar" [src]="user.avatar" alt="user_picture">
  <div class="infos">
    <div class="username">{{ user.username }}</div>
    <div>{{ user.email }}</div>
    <div class="gender">{{ user.gender }}</div>
  </div>
</div>

在路由组件UsersList(主要<router-outlet>)中,我们需要在屏幕上显示用户列表:

<user
  *ngFor="let user of users
  [user]="user"
  (click)="selectUser(user)">
</user>

然后,当我们单击以从列表中选择一个用户时,我们将使用相同的User组件显示选定的用户数据,但这次将其作为路由组件(命名为<router-outlet name="selected">):

Application Mockup

这是我们的路线:

const ROUTES: Routes = [
  {
    path: '',
    component: UsersList
  },
  {
    path: ':username',
    component: UserComponent,
    outlet: 'selected'
  }
];

因此,这里是selectUser()函数:

selectUser(user: User) {
  return this.router.navigate([ { outlets: { selected: [ user.username ] } } ], { state: { user } });
}

在我们的User组件中,我们需要实现OnInit接口:

if (this.route.outlet === 'selected') {
  this.route.paramMap.pipe(map(() => window.history.state)).subscribe(state => {
    if (!state.user) {
      return this.router.navigate([ { outlets: { selected: null } } ]);
    }
    this.user = state.user;
  });
}

所有这些都很好!我想知道的是,这样做是否是个好习惯吗?

仅供参考,我也尝试过使用路由解析器,但是我无法访问NavigationExtras state对象……在解析器内部获取用户数据的唯一方法是:将其作为queryParams传递。当我们有3个属性时可能会很好,但是,如果我们有10个以上属性,URL就会变得丑陋和混乱。而且,解析程序的作用似乎是解析异步数据而不传递静态数据。

感谢您的见解!

1 个答案:

答案 0 :(得分:0)

一种好的做法,或者说“成角度的方式”,就是使用路由解析器,其用法如文档https://angular.io/guide/router#fetch-data-before-navigating中所述。

我会尽可能使用解析器,因此我可以编写干净的页面组件,以便在实例化时从路由器获取所需的数据(我也可以将解析器重新用于其他路由,但这很少发生)。

这也使路由彼此独立:在进入用户列表页面之前,我可以看到用户页面,我认为我不能用您当前的代码来实现。另外,如果用户不存在,我可以直接从解析器重定向到404页面。

顺便说一句,解析器可能要记住一些缺点:

  • 如果您使用实时异步数据,则会丢失实时更新,因为文档仅获取了一次(通常由take(1)获取)并且流被关闭了
  • 如果您使用的是Ionic之类的东西来缓存页面,则可能是过时的数据出现问题