问题描述
以下是我的Angular应用中的表格.它填充了来自employees.json
:
Below is a table in my Angular app. It is populated with data from employees.json
:
<tbody>
<tr *ngFor="let employee of employees">
<td (click)="viewEmployeeProfile(1, employee.id)">{{employee.fullName}}
</td>
</tr>
</tbody>
当用户单击名称时,employeeId
会传递给此方法:
When the user clicks on a name, the employeeId
is passed to this method:
viewEmployeeProfile(roleId: number, employeeId: number) {
this._router.navigate(['/profile', roleId, employeeId]);
}
这是我的AppRouting
模块中的路线:
Here is the route in my AppRouting
module:
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
组件时,此代码称为:
When the user routes to theProfile
component, this code is called:
profile.component.ts:
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:
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));
}
此代码可以正常工作,&按预期显示数据.
This code is working fine, & displays data as expected.
当前,如果我导航到诸如http://localhost:4200/profile/1/123456789
的路由,而该employeeId
不存在,则显示Profile
组件时将不显示任何数据.
Currently, if I navigate to a route such as http://localhost:4200/profile/1/123456789
, where that employeeId
does not exist, the Profile
component is displayed with no data.
相反,我希望将用户带回PageNotFound
组件.
Instead of this, I would want the user to be brought back to the PageNotFound
component.
这是我当前的路线:
const routes: Routes = [
{ path: 'profile/:role/:id', component: ProfileComponent },
{ path: '**', component: PageNotFoundComponent }
];
有人可以告诉我实施此操作需要做哪些更改吗?
Can someone please tell me what changes I need to make to implement this?
推荐答案
对于 CanActivate 卫队.
自Angular 7.1.0起,路由保护程序现在可以返回 URLTree ,它为我们提供了一些帮助在我们的后卫中非常酷的灵活性. 这里很不错有关更改及其含义/使用方法的文章.
Since Angular 7.1.0, route guards may now return a URLTree which gives us some really cool flexibility in our guards. Here is a nice article that goes over the changes and what they mean / how they can be used.
我建议您建立警卫队.类似于以下内容:
I would suggest you create your guard. Something like the following:
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'))
);
}
}
从这里开始,只需转到路由模块",导入此防护并将其添加到您的路由中,如下所示:
From here, just go to your Routing Module, import this guard and add it to your route like this:
{
path: 'profile/:role/:id',
component: ProfileComponent,
canActivate: [RequireEmployeeProfileGuard]
}
我也可能会为错误组件定义一个明确命名的路由,例如:
I would also probably define an explicitly named route for the error component too like:
{
path: 'page-not-found',
component: PageNotFoundComponent
}
因此,上面的后卫中的'absolute-redirect-url-here'
将变为'page-not-found'
.
So then 'absolute-redirect-url-here'
from the guard above would become 'page-not-found'
.
此外,由于您仍然希望对无效的网址采用全包"格式,因此您可能希望使用类似以下的路由:
Also, since you would still want to have a 'catch-all' case for invalid URLs, you would probably want a route like:
{
path: '**',
redirectTo: 'page-not-found'
}
那么这是怎么工作的?
它可能看起来很复杂,但实际上它非常简单.魔术在于我们添加到后卫的canActivate()
方法中:
It might look complex but it's very simple at its core really. The magic is in the canActivate()
method that we added to the guard:
我们正在从employeeService
请求雇员资料,并使用double-not运算符将其转换为布尔值(基本上,检查我们是否有匹配的雇员资料").如果将其转换为false
,则返回URLTree
,它将把路由器重定向到指定的绝对路由.
We are requesting the employee profile from the employeeService
and converting it to a boolean using the double-not operator (basically, checking "do we have a matching employee profile"). If this converts to a false
then the URLTree
is returned which will redirect the router to the specified, absolute route.
当解决任何一条路线时,Angular将按照预定义的顺序遍历所有与之相连的防护装置.如果警卫的任何失败",则不会加载该路由.
When any route is being resolved, Angular will run through all the guards attached to it in a pre-defined order. If any of the guards 'fail' then the route won't be loaded.
这篇关于如果HTTP GET请求未返回数据,如何保护路由?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!