Angular: Setup routes depending on service method

2019-04-24 16:14发布

问题:

I have route configuration set up via @NgModule. And I have a service that identifies what parts of the application should be shown for the user depending on certain conditions. I need to call that service and setup the routes according to the returned value.

Problem: Route configuration is setup inside an annotation and I can't get how to call the service in such setup.

To be more specific here is the example configuration I want to enhance.

My current routing setup:

const appRoutes: Routes = [
    {
        path: '',
        redirectTo: 'first-route',
        pathMatch: 'full'
    },
    {
        path: 'first-route',
        component: FirstComponent,
        pathMatch: 'full'
    },
    {
        path: 'second-route',
        component: SecondComponent,
        pathMatch: 'full'
    },
    ...
];

@NgModule({
    imports: [RouterModule.forChild(appRoutes)],
    exports: [RouterModule]
})
export class MyRoutingModule {
}

The service that should change the route setup:

@Injectable()
export class MyService {
    getAccessibleRoutes(): Observable<string[]> {...}
}

Question: How can I make a service call and change the routes?

Note: I also looked on "Dynamically adding routes in Angular" and "How we can add new routes dynamically into RouterModule(@NgModule imports)" but I haven't found clear answer there.

回答1:

If I correctly understood your problem, I think you probably can consider using route guards to reach you goal. I suggest you to use guards feature to specify the conditions of accessing your routes, instead of changing the list of routes.

Please check this link for more information about route guards:

https://codecraft.tv/courses/angular/routing/router-guards/

I hope this will help you.

import { Injectable } from '@angular/core';
import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { YourSecurityService } from './your-security.service';

@Injectable()
export class YourRouteGuardService implements CanActivate {

    constructor(
        private router: Router, 
        private yourSecurityService: YourSecurityService) {
    }

    canActivate(
        route: ActivatedRouteSnapshot, 
        state: RouterStateSnapshot): boolean {

        console.log(state.url); // HERE YOU CAN GET REQUESTED ROUTE

        if (this.yourSecurityService.checkIfUserHaveAccess())
            return true;

        this.router.navigate(['your-route-to-redirect']);
        return false;
    }
 }

Next you should apply your guard to your route:

const appRoutes: Routes = [
    {
        path: 'someroute',
        component: RouteComponent,
        canActivate: [YourRouteGuardService]
    },
    ...
]