如何在角度路由模块中设置动态数据

时间:2021-07-03 10:19:59

标签: angular

我的 Angular 应用程序面临以下情况。

我设计了一个使用运行时配置的 Angular 应用程序,以便在使用 config.json 中的 APP_INITIALIZER 提供程序引导应用程序之前读取 AppModule 文件中的配置。来自配置文件的数据通过 AppConfiguration 服务作为 AppConfigService 对象提供。这按预期工作。

出现问题是因为我希望 role 中路由 dataAppRoutingModule 属性是可配置的,并且该值必须由包含我的配置的 AppConfigService 提供.

这就是我处理这种情况的方式:

AppModule 类中,我以这种方式初始化应用程序:

app.module.ts

@NgModule({
  declarations: [
  ...  
  ],
  imports: [
  ...
  ],
  entryComponents: [
  ...
  ],
  schemas: [NO_ERRORS_SCHEMA, CUSTOM_ELEMENTS_SCHEMA],
  providers: [
    {
      provide: APP_INITIALIZER,
      useFactory: initializer,
      multi: true,
      deps: [AppConfigService, KeycloakService],
    },
    ...
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

在初始化函数中,我调用了 AppConfigService::loadConfig 方法,该方法从 config.json 文件中读取数据并填充 AppConfiguration 对象。

app-init.ts

export function initializer(configService: AppConfigService, keycloak: KeycloakService): () => Promise<boolean> {
  return () => {
    // Load configuration from config.json file
    return configService.loadConfig()
      .then((): Promise<boolean> => {
        // Initialize keycloak
        ...
      });
  };
}

app-config.service.ts

@Injectable({
  providedIn: 'root'
})
export class AppConfigService {

  private _configuration: AppConfiguration;

  public get configuration() {
    return this._configuration;
  }

  constructor(private httpClient: HttpClient) { }

  public async loadConfig() {
    try {
      const data: AppConfiguration = await this.httpClient
          .get<AppConfiguration>(AppSettings.CONFIG_JSON_FILE)
          .toPromise();
      this._configuration = data;
    } catch (err) {
      console.error(err.error);
    }
  }
}

在我的 AppRoutingModule 中,我尝试在配置中的 role 中设置 routes 值:data: { roles: [this.configuration.role] }

app-routing.module.ts

const routes: Routes = [
  ...
  { path: 'openOrders', component: OpenOrderListComponent, canActivate: [AuthGuardService], data: { roles: [this.configuration.role] } },
  ...
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
  providers: [AuthGuardService, AppConfigService]
})
export class AppRoutingModule {
  private configuration: AppConfiguration;

  constructor(configService: AppConfigService) {
    this.configuration = configService.configuration;
  }
}

不幸的是,我在构建过程中收到此错误:

<块引用>

错误在 app/app-routing.module.ts(27,7): 模板过程中出错 编译“AppRoutingModule”对本地(非导出)的引用 装饰器不支持符号,但引用了“路由”
考虑导出“路线”。

我怎样才能克服这个问题?我想这是一个天真的问题,但我不知道如何解决这个错误(记住我是 angular 的新手)。

非常感谢。

PS:我使用的是角度版本:

<块引用>

Angular CLI:7.0.7
节点:12.21.0
操作系统:linux x64
角度:7.0.0

1 个答案:

答案 0 :(得分:0)

最后我采用了不同的方法。我没有在数据属性中注入可配置值,而是在使用该数据值的代码中注入了该值。

因此我从路由中删除了 data 属性:

const routes: Routes = [
  ...
  { path: 'openOrders', component: OpenOrderListComponent, canActivate: [AuthGuardService] },
  ...
];

角色数据用于AuthGuardService。我所要做的就是在这个类中注入 AppConfigService 并使用 AppConfiguration 中的角色值而不是路由数据中的值:

@Injectable()
export class AuthGuardService extends KeycloakAuthGuard {
  configuration: AppConfiguration;
  ...
  constructor(protected router: Router,
              protected keycloakAngular: KeycloakService,
              protected configService: AppConfigService) {
    super(router, keycloakAngular);
    this.configuration = configService.configuration;
  }

  isAccessAllowed(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
  ...
      const requiredRoles: string[] = [this.configuration.role];
  ...
  }