/** * @license * Copyright Google Inc. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ import {Observable} from 'rxjs'; import {Route} from './config'; import {ActivatedRouteSnapshot, RouterStateSnapshot} from './router_state'; import {UrlSegment, UrlTree} from './url_tree'; /** * @description * * Interface that a class can implement to be a guard deciding if a route can be activated. * If all guards return `true`, navigation will continue. If any guard returns `false`, * navigation will be cancelled. If any guard returns a `UrlTree`, current navigation will * be cancelled and a new navigation will be kicked off to the `UrlTree` returned from the * guard. * * ``` * class UserToken {} * class Permissions { * canActivate(user: UserToken, id: string): boolean { * return true; * } * } * * @Injectable() * class CanActivateTeam implements CanActivate { * constructor(private permissions: Permissions, private currentUser: UserToken) {} * * canActivate( * route: ActivatedRouteSnapshot, * state: RouterStateSnapshot * ): Observable|Promise|boolean|UrlTree { * return this.permissions.canActivate(this.currentUser, route.params.id); * } * } * * @NgModule({ * imports: [ * RouterModule.forRoot([ * { * path: 'team/:id', * component: TeamComponent, * canActivate: [CanActivateTeam] * } * ]) * ], * providers: [CanActivateTeam, UserToken, Permissions] * }) * class AppModule {} * ``` * * You can alternatively provide a function with the `canActivate` signature: * * ``` * @NgModule({ * imports: [ * RouterModule.forRoot([ * { * path: 'team/:id', * component: TeamComponent, * canActivate: ['canActivateTeam'] * } * ]) * ], * providers: [ * { * provide: 'canActivateTeam', * useValue: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => true * } * ] * }) * class AppModule {} * ``` * * @publicApi */ export interface CanActivate { canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable|Promise|boolean|UrlTree; } export type CanActivateFn = (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => Observable| Promise| boolean | UrlTree; /** * @description * * Interface that a class can implement to be a guard deciding if a child route can be activated. * If all guards return `true`, navigation will continue. If any guard returns `false`, * navigation will be cancelled. If any guard returns a `UrlTree`, current navigation will * be cancelled and a new navigation will be kicked off to the `UrlTree` returned from the * guard. * * ``` * class UserToken {} * class Permissions { * canActivate(user: UserToken, id: string): boolean { * return true; * } * } * * @Injectable() * class CanActivateTeam implements CanActivateChild { * constructor(private permissions: Permissions, private currentUser: UserToken) {} * * canActivateChild( * route: ActivatedRouteSnapshot, * state: RouterStateSnapshot * ): Observable|Promise|boolean|UrlTree { * return this.permissions.canActivate(this.currentUser, route.params.id); * } * } * * @NgModule({ * imports: [ * RouterModule.forRoot([ * { * path: 'root', * canActivateChild: [CanActivateTeam], * children: [ * { * path: 'team/:id', * component: TeamComponent * } * ] * } * ]) * ], * providers: [CanActivateTeam, UserToken, Permissions] * }) * class AppModule {} * ``` * * You can alternatively provide a function with the `canActivateChild` signature: * * ``` * @NgModule({ * imports: [ * RouterModule.forRoot([ * { * path: 'root', * canActivateChild: ['canActivateTeam'], * children: [ * { * path: 'team/:id', * component: TeamComponent * } * ] * } * ]) * ], * providers: [ * { * provide: 'canActivateTeam', * useValue: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => true * } * ] * }) * class AppModule {} * ``` * * @publicApi */ export interface CanActivateChild { canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable|Promise|boolean|UrlTree; } export type CanActivateChildFn = (childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot) => Observable| Promise| boolean | UrlTree; /** * @description * * Interface that a class can implement to be a guard deciding if a route can be deactivated. * If all guards return `true`, navigation will continue. If any guard returns `false`, * navigation will be cancelled. If any guard returns a `UrlTree`, current navigation will * be cancelled and a new navigation will be kicked off to the `UrlTree` returned from the * guard. * * ``` * class UserToken {} * class Permissions { * canDeactivate(user: UserToken, id: string): boolean { * return true; * } * } * * @Injectable() * class CanDeactivateTeam implements CanDeactivate { * constructor(private permissions: Permissions, private currentUser: UserToken) {} * * canDeactivate( * component: TeamComponent, * currentRoute: ActivatedRouteSnapshot, * currentState: RouterStateSnapshot, * nextState: RouterStateSnapshot * ): Observable|Promise|boolean|UrlTree { * return this.permissions.canDeactivate(this.currentUser, route.params.id); * } * } * * @NgModule({ * imports: [ * RouterModule.forRoot([ * { * path: 'team/:id', * component: TeamComponent, * canDeactivate: [CanDeactivateTeam] * } * ]) * ], * providers: [CanDeactivateTeam, UserToken, Permissions] * }) * class AppModule {} * ``` * * You can alternatively provide a function with the `canDeactivate` signature: * * ``` * @NgModule({ * imports: [ * RouterModule.forRoot([ * { * path: 'team/:id', * component: TeamComponent, * canDeactivate: ['canDeactivateTeam'] * } * ]) * ], * providers: [ * { * provide: 'canDeactivateTeam', * useValue: (component: TeamComponent, currentRoute: ActivatedRouteSnapshot, currentState: * RouterStateSnapshot, nextState: RouterStateSnapshot) => true * } * ] * }) * class AppModule {} * ``` * * @publicApi */ export interface CanDeactivate { canDeactivate( component: T, currentRoute: ActivatedRouteSnapshot, currentState: RouterStateSnapshot, nextState?: RouterStateSnapshot): Observable|Promise|boolean |UrlTree; } export type CanDeactivateFn = (component: T, currentRoute: ActivatedRouteSnapshot, currentState: RouterStateSnapshot, nextState?: RouterStateSnapshot) => Observable| Promise| boolean | UrlTree; /** * @description * * Interface that classes can implement to be a data provider. * A data provider class can be used with the router to resolve data during navigation. * The interface defines a `resolve()` method that will be invoked when the navigation starts. * The router will then wait for the data to be resolved before the route is finally activated. * * ``` * @Injectable({ providedIn: 'root' }) * export class HeroResolver implements Resolve { * constructor(private service: HeroService) {} * * resolve( * route: ActivatedRouteSnapshot, * state: RouterStateSnapshot * ): Observable|Promise|any { * return this.service.getHero(route.paramMap.get('id')); * } * } * * @NgModule({ * imports: [ * RouterModule.forRoot([ * { * path: 'detail/:id', * component: HeroDetailComponent, * resolve: { * hero: HeroResolver * } * } * ]) * ], * exports: [RouterModule] * }) * export class AppRoutingModule {} * ``` * * You can alternatively provide a function with the `resolve` signature: * * ``` * export const myHero: Hero = { * // ... * } * * @NgModule({ * imports: [ * RouterModule.forRoot([ * { * path: 'detail/:id', * component: HeroComponent, * resolve: { * hero: 'heroResolver' * } * } * ]) * ], * providers: [ * { * provide: 'heroResolver', * useValue: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => myHero * } * ] * }) * export class AppModule {} * ``` * * @publicApi */ export interface Resolve { resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable|Promise|T; } /** * @description * * Interface that a class can implement to be a guard deciding if children can be loaded. * * ``` * class UserToken {} * class Permissions { * canLoadChildren(user: UserToken, id: string, segments: UrlSegment[]): boolean { * return true; * } * } * * @Injectable() * class CanLoadTeamSection implements CanLoad { * constructor(private permissions: Permissions, private currentUser: UserToken) {} * * canLoad(route: Route, segments: UrlSegment[]): Observable|Promise|boolean { * return this.permissions.canLoadChildren(this.currentUser, route, segments); * } * } * * @NgModule({ * imports: [ * RouterModule.forRoot([ * { * path: 'team/:id', * component: TeamComponent, * loadChildren: 'team.js', * canLoad: [CanLoadTeamSection] * } * ]) * ], * providers: [CanLoadTeamSection, UserToken, Permissions] * }) * class AppModule {} * ``` * * You can alternatively provide a function with the `canLoad` signature: * * ``` * @NgModule({ * imports: [ * RouterModule.forRoot([ * { * path: 'team/:id', * component: TeamComponent, * loadChildren: 'team.js', * canLoad: ['canLoadTeamSection'] * } * ]) * ], * providers: [ * { * provide: 'canLoadTeamSection', * useValue: (route: Route, segments: UrlSegment[]) => true * } * ] * }) * class AppModule {} * ``` * * @publicApi */ export interface CanLoad { canLoad(route: Route, segments: UrlSegment[]): Observable|Promise|boolean; } export type CanLoadFn = (route: Route, segments: UrlSegment[]) => Observable| Promise| boolean;