简体   繁体   English

如何使angular2模块(ngModule)可配置

[英]How to make a angular2 module (ngModule) configurable

Assuming that we have a module which does some authentication stuff in it. 假设我们有一个模块可以在其中执行一些身份验证。

I want to set some variables while adding the module to the project. 我想在将模块添加到项目时设置一些变量。

I've seen that the routing module does something similar with the function forRoot(routes) . 我已经看到路由模块与功能forRoot(routes)类似。

So I tried the same but it kind a feels not correct. 所以我尝试了同样但感觉不正确。

My authentication module (should be configurable) 我的身份验证模块(应该是可配置的)

@NgModule({
  imports: [
    CommonModule
  ],
  declarations: [],
  providers: []
})
export class AuthenticationModule {
  static forRoot(authMode: AuthMode) {
    return {
      ngModule: AuthenticationModule,
      providers: [
        {
          useValue: authMode,
          provide: AuthMode
        },
        {
          provide: AuthenticationGuard,
          useFactory: authFactory,
          deps: [AuthMode, Router]
        }
      ]
    }
  }
}

export function authFactory(authMode: AuthMode, router: Router) {
  return new AuthenticationGuard(authMode, router);
}

AuthMode is just a enum holding a value, to compare the selected mode later on in the AuthenticationGuard . AuthMode只是一个包含值的enum ,以便稍后在AuthenticationGuard比较所选模式。

My app.module.ts adds the module like this: 我的app.module.ts添加了这样的模块:

@NgModule({
  declarations: [ // some stuff ]
  imports: [
    BrowserModule,
    // ... some other stuff
    AuthenticationModule.forRoot(AuthMode.OAuthLocalStorage)
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {
}

The AuthenticationGuard injects the authMode by value like this: AuthenticationGuard按值注入authMode ,如下所示:

@Injectable()
export class AuthenticationGuard implements CanActivate {
  public storage: Storage;

  constructor(@Inject(AuthMode) authMode, private router: Router) {
    console.log('selected authMode is ', AuthMode[authMode]);
}

This works fine when using the guard with the routes and canActivate property. 当使用具有路由和canActivate属性的guard时,这可以正常工作。 But once I inject it to some other service (inside another module), I get this error: 但是一旦我将它注入其他服务(在另一个模块内),我就会收到此错误:

Error: Invalid provider for the NgModule 'AuthenticationModule' - only instances of Provider and Type are allowed, got: [?undefined?, ...] at SyntaxError.ZoneAwareError 错误:NgModule'AuthenticationModule'的提供程序无效 - 只允许Provider和Type的实例,在SyntaxError.ZoneAwareError得到:[?undefined?,...]

So my basic question would be: 所以我的基本问题是:

  • Is this the way how to make a ngModule configurable 这是如何使ngModule可配置的方式
  • And what would solve the problem above? 什么能解决上面的问题?

Build with Angular 2 and angular-cli (beta 25) 使用Angular 2和angular-cli构建(beta 25)

What about storing the setting in a special variable and using a factory to inject it? 将设置存储在特殊变量中并使用工厂注入它怎么样?

let authModeSetting: AuthMode;

@NgModule({
  imports: [
    CommonModule
  ],
  providers: [
    {
      useFactory: () => authModeSetting,
      provide: AuthMode
    },
    AuthenticationGuard
  ]
})
export class AuthenticationModule {

  static forRoot(authMode: AuthMode) {
    authModeSetting = authMode;

    return AuthenticationModule;
  }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM