angular - Làm thế nào để chỉ định phương thức gọi dựa trên tham số tuyến đường?
Tôi có một ProfileComponent trong ứng dụng Angular của mình, cũng như 2 tệp JSON - employees.json & managers.json
Trước đây, tôi đã sử dụng kiểm tra sau trong profile.component.ts:
ngOnInit() {
this.route.paramMap.subscribe(params => {
const roleId = +params.get('role');
const empId = +params.get('id');
if (empId) {
if (roleId === 1) {
this.getEmployee(empId);
} else if (roleId === 2) {
this.getManager(empId);
}
}
});
}
HTML :
<td (click)="viewEmployeeProfile(1, employee.id)">{{employee.fullName}}</td>
<td (click)="viewEmployeeProfile(2, manager.id)">{{manager.fullName}}</td>
Nếu roleId=1, hiển thị dữ liệu từ employees.json, nếu roleId=2 thì hiển thị dữ liệu từ managers.json
Đây là các phương pháp của tôi:
getEmployee(id: number) {
this.employeeService.getEmployee(id).subscribe(
(employee: IEmployee) => this.displayEmployee(employee),
(err: any) => console.log(err)
);
}
getManager(id: number) {
this.managerService.getManager(id).subscribe(
(manager: IManager) => this.displayManager(manager),
(err: any) => console.log(err)
);
}
Và đây là các phương pháp trong dịch vụ của tôi:
Employee ServicebaseUrl = 'http://localhost:3000/employees';
getEmployee(id: number): Observable<IEmployee> {
return this.httpClient.get<IEmployee>(`${this.baseUrl}/${id}`)
.pipe(catchError(this.handleError));
}
Manager ServicebaseUrl = 'http://localhost:3000/managers';
getManager(id: number): Observable<IManager> {
return this.httpClient.get<IManager>(`${this.baseUrl}/${id}`)
.pipe(catchError(this.handleError));
}
Trước đây điều này đã hoạt động, nhưng kể từ đó tôi đã quyết định thêm bảo vệ canActivate() để ngăn người dùng điều hướng đến thành phần Profile với ID không hợp lệ.
Đây là lộ trình của tôi:
{
path: 'profile/:role/:id', component: ProfileComponent,
canActivate: [RequireEmployeeProfileGuardGuard]
}
Và đây là những gì tôi có trong phòng gác của mình:
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'))
);
}
Bây giờ, khi tôi tìm kiếm một Nhân viên, ứng dụng hoạt động tốt vì nó đang tìm kiếm employees.json. Nhưng, nếu tôi chọn hiển thị một Quản lý, nó sẽ bị lỗi vì nó đang tìm kiếm employees.json theo ID của Quản lý.
Ai đó có thể chỉ ra những thay đổi tôi cần thực hiện để mã của tôi tìm kiếm đúng tệp không?
Câu trả lời #1
Bạn có thể có phương thức canActivate của mình như những gì bạn đang làm trong component như sau:
canActivate(route: ActivatedRouteSnapshot): Observable<boolean | UrlTree> {
const roleId = +route.paramMap.get('role');
const empId = +route.paramMap.get('id');
if(roleId === 1) {
//employee
return this.employeeService.getEmployee(empId)
.pipe(
map(employee => {
if(employee) {
return true;
} else {
this.router.parseUrl('page-not-found');
return false;
}
})
);
} else if(roleId === 2) {
//manager
return this.managerService.getManager(empId)
.pipe(
map(manager => {
if(manager) {
return true;
} else {
this.router.parseUrl('page-not-found');
return false;
}
})
);
} else {
//do not pass the guard
of(false);
}
}
Để tránh việc trùng lặp mã, bạn có thể có một hàm bậc cao như sau:
canActivate(route: ActivatedRouteSnapshot): Observable<boolean | UrlTree> {
const roleId = +route.paramMap.get('role');
const empId = +route.paramMap.get('id');
const myMap = map(emp => {
if(emp) {
return true;
} else {
this.router.parseUrl('page-not-found');
return false;
}
})
if(roleId === 1) {
return this.employeeService.getEmployee(empId)
.pipe(
myMap
);
} else if(roleId === 2) {
return this.managerService.getManager(empId)
.pipe(
myMap
);
} else {
//do not pass the guard
of(false);
}
}
