angular - Kuinka määrittää kutsuttava metodi reititysparametrin perusteella?
Minulla on ProfileComponent Angular-sovelluksessani, sekä 2 JSON-tiedostoa - employees.json & managers.json
Aiemmin käytin seuraavaa tarkistusta tiedostossa 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>
Jos roleId=1, näytä tiedot tiedostosta employees.json, jos roleId=2, näytä tiedot tiedostosta managers.json
Tässä ovat menetelmäni:
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)
);
}
Ja tässä ovat menetelmät palveluissani:
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));
}
Tämä toimi aiemmin, mutta olen sen jälkeen päättänyt lisätä canActivate()-suojan estääkseni käyttäjiä siirtymästä Profiili-komponenttiin virheellisellä ID:llä.
Tässä on reittini:
{
path: 'profile/:role/:id', component: ProfileComponent,
canActivate: [RequireEmployeeProfileGuardGuard]
}
Ja tässä on mitä minulla on vartiossani:
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'))
);
}
Nyt, kun haen työntekijää, sovellus toimii hyvin, koska se etsii employees.json-tiedostosta. Mutta jos valitsen näyttää johtajan, se epäonnistuu, koska se etsii employees.json-tiedostosta johtajan tunnusta.
Voisiko joku ystävällisesti osoittaa, mitä muutoksia minun täytyy tehdä, jotta koodini etsii oikeaa tiedostoa?
Vastaus #1
Voit saada canActivate-metodisi toimimaan kuten teit komponentissa näin:
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);
}
}
Välttääksesi koodin toistamisen voit käyttää tällaista korkeampaa järjestyksen funktiota:
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);
}
}
