我们有一个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">
):
这是我们的路线:
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就会变得丑陋和混乱。而且,解析程序的作用似乎是解析异步数据而不传递静态数据。
感谢您的见解!
答案 0 :(得分:0)
一种好的做法,或者说“成角度的方式”,就是使用路由解析器,其用法如文档https://angular.io/guide/router#fetch-data-before-navigating中所述。
我会尽可能使用解析器,因此我可以编写干净的页面组件,以便在实例化时从路由器获取所需的数据(我也可以将解析器重新用于其他路由,但这很少发生)。
这也使路由彼此独立:在进入用户列表页面之前,我可以看到用户页面,我认为我不能用您当前的代码来实现。另外,如果用户不存在,我可以直接从解析器重定向到404页面。
顺便说一句,解析器可能要记住一些缺点: