无法在 Angular 中使用 canDeActivate 或 canActivate

Unable to use canDeActivate or canActivate in Angular

我正在尝试使用 canDeActivate 和 canActivate,我将其与 Angular 4 一起使用,如下所示。我得到了相同的 no provider error。实现有什么问题,或者干净简单地实现它的正确方法是什么。

import {ModuleWithProviders, } from '@angular/core';

    import {Routes, RouterModule, RouterStateSnapshot, ActivatedRouteSnapshot, CanDeactivate} from '@angular/router';


    import {HomeComponent} from '../home/home.component';

    var x: any = true;

    const appRoutes: Routes = [
        {path: '', component: HomeComponent, canDeactivate: [true]},
        {path: 'test', component: HomeComponent, canDeactivate: [x]},

    ];

    export const appRoutingProviders: any[] = [];

    export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);

错误更新:

ERROR Error: Uncaught (in promise): Error: No provider for true!
Error: No provider for true!
    at injectionError (reflective_errors.ts:71)
    at noProviderError (reflective_errors.ts:105)
    at ReflectiveInjector_._throwOrNull (reflective_injector.ts:500)
    at ReflectiveInjector_._getByKeyDefault (reflective_injector.ts:543)
    at ReflectiveInjector_._getByKey (reflective_injector.ts:404)
    at ReflectiveInjector_.get (reflective_injector.ts:349)
    at AppModuleInjector.NgModuleInjector.get (ng_module_factory.ts:141)
    at PreActivation.getToken (router.ts:1232)
    at MergeMapSubscriber.eval [as project] (router.ts:1191)
    at MergeMapSubscriber._tryNext (mergeMap.ts:125)
    at injectionError (reflective_errors.ts:71)
    at noProviderError (reflective_errors.ts:105)
    at ReflectiveInjector_._throwOrNull (reflective_injector.ts:500)
    at ReflectiveInjector_._getByKeyDefault (reflective_injector.ts:543)
    at ReflectiveInjector_._getByKey (reflective_injector.ts:404)
    at ReflectiveInjector_.get (reflective_injector.ts:349)
    at AppModuleInjector.NgModuleInjector.get (ng_module_factory.ts:141)
    at PreActivation.getToken (router.ts:1232)
    at MergeMapSubscriber.eval [as project] (router.ts:1191)
    at MergeMapSubscriber._tryNext (mergeMap.ts:125)
    at resolvePromise (zone.js:769)
    at resolvePromise (zone.js:740)
    at zone.js:817
    at ZoneDelegate.invokeTask (zone.js:424)
    at Object.onInvokeTask (ng_zone.ts:253)
    at ZoneDelegate.invokeTask (zone.js:423)
    at Zone.runTask (zone.js:191)
    at drainMicroTaskQueue (zone.js:584)
    at HTMLAnchorElement.ZoneTask.invoke (zone.js:490)

所有守卫都拿一个指向函数或class引用的令牌。这是一个作为守卫的函数的简单示例:

 // create a token
 const token = new InjectionToken('name');

 // register the provider by that token
 providers: [{provide: token, useValue: function() {} }]

 // use this token in a guard
 const appRoutes: Routes = [
     {path: '', component: HomeComponent, canDeactivate: [token]},
 ];

通常您不会显式创建令牌,但它是通过引用 class 创建的,当您像这样使用它时:

@Injectable()
class CanActivateContacts {
    constructor() {}
    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot)

@NgModule({
    providers: [CanActivateContacts] <------ token is implicitly created here
})
class AppModule

const appRoutes: Routes = [
    {path: '', component: HomeComponent, canDeactivate: [CanActivateContacts]},
];