代码之家  ›  专栏  ›  技术社区  ›  Kingamere

为什么ngoninit()在canActivate()之前被调用?

  •  1
  • Kingamere  · 技术社区  · 6 年前

    我用的是巡警,特别是 canActivate() 方法,但Angular正在调用 ngOnInit() 我的根 AppComponent 之前 canActivate 被称为。

    我得等一些数据 激活 之前 附加组件 可以在模板中呈现。

    我该怎么做?

    1 回复  |  直到 6 年前
        1
  •  2
  •   montrealist    6 年前

    我在处理这些案子,我通常做的是:

    1。 我创建了一个 旋转变压器 服务(实现 Resolve 接口。它能让你得到所有必要的数据 之前 激活路由:

    import { Injectable } from '@angular/core';
    import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
    import { DataService } from 'path/to/data.service';
    
    @Injectable()
    export class ExampleResolverService implements Resolve<any> {
      constructor(private _dataService: DataService) { }
    
      resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<any> {
        return this._dataService.anyAsyncCall()
          .then(response => {
            /* Let's imagine, that this method returns response with field "result", which can be equal to "true" or "false" */
            /* "setResult" just stores passed argument to "DataService" class property */
            this._dataService.setResult(response.result);
          })
          .catch(err => this._dataService.setResult(false););
      }
    }
    

    2。 我们可以这样处理 卫士 ,它实现了 CanActivate 接口:

    import { Injectable } from '@angular/core';
    import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router';
    import { DataService } from 'path/to/data.service';
    
    @Injectable()
    export class AuthGuard implements CanActivate {
      constructor(private _dataService: DataService) { }
    
      canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
        /* "getResult" method operates with the same class property as setResult, it just returns the value of it */
        return this._dataService.getResult(); // will return "true" or "false"
      }
    }
    

    三。 然后你可以包括 旋转变压器 还有 卫士 对于路由配置,这里只是一部分(路由的结构可能不同,下面是激活父组件的示例):

    const routes: Routes = [
      {
        path: 'app',
        component: AppComponent,
        resolve: {
          result: ExampleResolverService // your resolver
        },
        canActivate: [AuthGuard], // your AuthGuard with "canActivate" method
        children: [...] // child routes goes inside the array
      }
    ];
    

    它是如何工作的

    当你导航到 /app , ExampleResolverService 启动、进行API调用并将类属性响应的必要部分存储在 DataService 通过 setResult 方法(通常是setter)。然后,当分解器完成工作时 AuthGuard . 它从 数据服务 通过 getResult 方法(它是常用的getter),并返回此布尔结果(我们的 卫士 期望返回布尔值,如果返回则激活路由 true ,如果返回,则不会激活 false ;

    这是一个最简单的例子,没有任何额外的数据操作,逻辑通常更复杂,但这个框架应该足够基本的理解。