以下是我的Angular应用中的表格。它用来自employees.json
的数据填充:
<tbody>
<tr *ngFor="let employee of employees">
<td (click)="viewEmployeeProfile(1, employee.id)">{{employee.fullName}}
</td>
</tr>
</tbody>
当用户单击名称时,employeeId
将传递给此方法:
viewEmployeeProfile(roleId: number, employeeId: number) {
this._router.navigate(['/profile', roleId, employeeId]);
}
这是我的AppRouting
模块中的路线:
const routes: Routes = [
{
path: 'profile/:role/:id',
component: ProfileComponent,
// canActivate: [RequireEmployeeProfileGuardGuard]
},
{
path: 'page-not-found',
component: PageNotFoundComponent
},
{
path: '**',
component: PageNotFoundComponent
}
];
示例路径:http://localhost:4200/profile/1/4
当用户转到Profile
组件时,此代码称为:
profile.component.ts:
ngOnInit() {
this.route.paramMap.subscribe(params => {
const roleId = +params.get('role');
const empId = +params.get('id');
this.getEmployee(empId);
});
}
getEmployee(id: number) {
this.employeeService.getEmployee(id).subscribe(
(employee: IEmployee) => this.displayEmployee(employee),
(err: any) => console.log(err)
);
}
displayEmployee(employee: IEmployee) {
this.employee.fullName = employee.fullName;
}
profile.component.html:
<tr>
<td><b>Full Name</b></td>
<td>{{employee.fullName}}</td>
</tr>
这是我的employee.service
:
baseUrl = 'http://localhost:3000/employees';
getEmployee(id: number): Observable<IEmployee> {
return this.httpClient.get<IEmployee>(`${this.baseUrl}/${id}`)
.pipe(catchError(this.handleError));
}
此代码运行正常,并按预期显示数据。
当前,如果我导航到http://localhost:4200/profile/1/123456789
之类的不存在employeeId
的路线,则Profile
组件将不显示任何数据。
相反,我希望将用户带回到PageNotFound
组件。
这是我当前的路线:
const routes: Routes = [
{ path: 'profile/:role/:id', component: ProfileComponent },
{ path: '**', component: PageNotFoundComponent }
];
有人可以告诉我实现此功能需要做哪些更改?
答案 0 :(得分:1)
对于CanActivate后卫来说,这是绝佳的机会。
自Angular 7.1.0起,路由守卫现在可以返回URLTree,这为我们的守卫提供了非常酷的灵活性。 Here是一篇不错的文章,介绍了更改及其含义/使用方式。
我建议您建立警卫队。类似于以下内容:
import { Injectable } from '@angular/core';
import { CanActivate, Router, UrlTree, ActivatedRouteSnapshot } from '@angular/router';
import { Observable, of } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
// import your employee service here
@Injectable()
export class RequireEmployeeProfileGuard implements CanActivate {
constructor(private router: Router, private employeeService: EmployeeService) {
}
canActivate(route: ActivatedRouteSnapshot): Observable<boolean | UrlTree> {
return this.employeeService.getEmployee(+route.paramMap.get('id')).pipe(
catchError(() => of(false)),
map(employee => !!employee || this.router.parseUrl('page-not-found'))
);
}
}
从这里开始,只需转到“路由模块”,导入该防护并将其添加到您的路由中,如下所示:
{
path: 'profile/:role/:id',
component: ProfileComponent,
canActivate: [RequireEmployeeProfileGuard]
}
我也可能会为错误组件定义一个明确命名的路由,例如:
{
path: 'page-not-found',
component: PageNotFoundComponent
}
因此,来自上方守卫的'absolute-redirect-url-here'
将变成'page-not-found'
。
此外,由于您仍然希望对无效的网址使用“全包”格式,因此您可能希望使用类似
的路由{
path: '**',
redirectTo: 'page-not-found'
}
那么这是如何工作的?
它看起来很复杂,但实际上它非常简单。神奇之处在于我们添加到后卫的canActivate()
方法中:
我们正在从employeeService
请求员工资料,并使用double-not运算符将其转换为布尔值(基本上,检查“我们是否有匹配的员工资料”)。如果将其转换为false
,则返回URLTree
,它将把路由器重定向到指定的绝对路由。
当解决任何路线时,Angular将以预定义的顺序遍历所有与之相连的防护装置。如果警卫的任何“失败”,则不会加载该路由。
答案 1 :(得分:0)
您可以修改getEmployee
方法,例如
getEmployee(id: number) {
this.employeeService.getEmployee(id).subscribe(
(employee: IEmployee) => {
if(employee){
this.displayEmployee(employee)
}else{
//redirect to page not found here
}
},
(err: any) => console.log(err)
);
}
答案 2 :(得分:0)
将下面的路由添加到AppRouting
模块
{path: '404', component: NotFoundComponent},
{path: '**', redirectTo: '/404'}
上述路由还将在根级和任何嵌套子级中捕获不正确的路由。将此路径作为路由模块中的最后一条路径
如果记录计数为0或为空,则从gotoHeroes
方法中调用getEmployee
方法
gotoHeroes() {
this.router.navigate(['/404']);
}