angular - 如何根据路由参数指定要调用的方法?

标签 angular typescript angular-httpclient

我的 Angular 应用程序中有一个 ProfileComponent,还有 2 个 JSON 文件 - employees.jsonmanagers.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)
    );
}

下面是我的服务中的方法:

员工服务

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

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

管理器服务

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

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

这在以前是有效的,但我后来决定添加 canActivate() 守卫以阻止用户使用无效 ID 导航到 Profile 组件。

这是我的路线:

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

这是我的 guard :

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

现在,当我搜索 Employee 时,应用程序运行正常,因为它正在搜索 employees.json。 但是,如果我选择显示经理,它会失败,因为它正在 employees.json 中搜索经理的 ID。

有人可以指出我需要进行哪些更改以便我的代码搜索正确的文件吗?

最佳答案

您可以像在组件中那样使用 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);
    }
}

关于angular - 如何根据路由参数指定要调用的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56757084/

相关文章:

javascript - 使用 Angular CLI 和 Angular 5 在运行时动态加载新模块

javascript - 使用 Enter/Space 键单击 <a> 元素不起作用,即使它已聚焦(可访问性)

CSS 过渡动画 Jank w/zindex on Mac (Retina)

javascript - TypeScript:你能根据函数的参数定义一个返回类型结构吗?

angular - 无法从 API 下载 blob 作为 Angular 7 中的文件

javascript - 在什么时候计算 scrollHeight

css - 更改单选按钮的大小

typescript - 如何限制泛型类型具有 new()?

angular - 尝试针对实时 REST API : nothing happens 运行 Angular HttpClient Jasmine 测试

c# - Angular 6 HttpClient Post 未命中 DotNet Core 2.2 API Controller 中的 API Post 方法