1

下面是我的 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,则该组件将显示为没有数据)。employeeIdProfile

而不是这个,我希望用户被带回PageNotFound组件。

以下是我目前的路线:

const routes: Routes = [
  { path: 'profile/:role/:id', component: ProfileComponent },
  { path: '**', component: PageNotFoundComponent }
];

有人可以告诉我我需要做哪些改变来实现这个吗?

4

3 回答 3

1

这是CanActivate守卫的绝佳机会。

从 Angular 7.1.0 开始,路由守卫现在可能会返回一个URLTree,这为我们的守卫提供了一些非常酷的灵活性。是一篇很好的文章,介绍了这些变化以及它们的含义/如何使用它们。

我建议你创建你的后卫。类似于以下内容:

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'

此外,由于您仍然希望对无效 URL 有一个“包罗万象”的情况,您可能需要这样的路由:

{ 
  path: '**', 
  redirectTo: 'page-not-found'
}

那么这是如何工作的呢?

它可能看起来很复杂,但实际上它的核心非常简单。神奇之处canActivate()在于我们添加到守卫的方法:

我们从 请求员工资料employeeService并使用双非运算符将其转换为布尔值(基本上,检查“我们是否有匹配的员工资料”)。如果这转换为 a false,则URLTree返回 ,这会将路由器重定向到指定的绝对路由。

当任何路由被解析时,Angular 将以预定义的顺序遍历所有附加到它的守卫。如果任何守卫“失败”,则不会加载路线。

于 2019-06-25T10:56:01.920 回答
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)
    );
}
于 2019-06-25T10:33:35.343 回答
0

将以下路由添加到AppRouting模块

{path: '404', component: NotFoundComponent},
{path: '**', redirectTo: '/404'}

上述路由将在根级别以及任何嵌套子级中捕获不正确的路由。将此路径作为路由模块中的最后一个路径

如果记录数为 0 或 null gotoHeroes,则从方法调用方法getEmployee

gotoHeroes() {
  this.router.navigate(['/404']);
}
于 2019-06-25T10:50:25.977 回答