Как указать метод для вызова на основе параметра маршрута? - PullRequest
2 голосов
/ 25 июня 2019

У меня в приложении Angular ProfileComponent, а также 2 файла JSON - employees.json & managers.json

Ранее я использовал следующую регистрацию в 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>

Если roleId = 1, отобразить данные из employees.json, если roleId = 2, отобразить данные из managers.json

Вот мои методы:

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)
    );
}

А вот методы в моих услугах:

Employee Service

baseUrl = 'http://localhost:3000/employees';

getEmployee(id: number): Observable<IEmployee> {
    return this.httpClient.get<IEmployee>(`${this.baseUrl}/${id}`)
        .pipe(catchError(this.handleError));
}

Manager Service

baseUrl = 'http://localhost:3000/managers';

getManager(id: number): Observable<IManager> {
     return this.httpClient.get<IManager>(`${this.baseUrl}/${id}`)
        .pipe(catchError(this.handleError));
}

Раньше это работало, но с тех пор я решил добавить защиту canActivate(), чтобы пользователь не переходил на компонент Profile с недопустимым идентификатором.

Вот мой маршрут:

{
    path: 'profile/:role/:id', component: ProfileComponent,
    canActivate: [RequireEmployeeProfileGuardGuard]
}

А вот что у меня на страже:

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'))
);
}

Теперь, когда я ищу сотрудника, приложение работает нормально, потому что оно ищет employees.json. Но, если я решу отобразить Диспетчер, он потерпит неудачу, потому что он ищет в employees.json идентификатор Менеджера.

Может кто-нибудь указать, какие изменения мне нужно внести, чтобы мой код искал нужный файл?

1 Ответ

1 голос
/ 25 июня 2019

Вы можете использовать свой canActivate метод, подобный тому, что вы делали в компоненте, например:

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);
    }
}

Чтобы избежать дублирования кода, вы можете использовать функцию более высокого порядка, например:

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);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...