Как сделать модуль angular2 (ngModule) настраиваемым

Предполагая, что у нас есть модуль, который выполняет некоторые действия по аутентификации.

Я хочу установить некоторые переменные при добавлении модуля в проект.

Я видел, что модуль маршрутизации делает что-то подобное с функцией forRoot(routes).

Итак, я попробовал то же самое, но это кажется неправильным.

Мой модуль аутентификации (должен быть настраиваемым)

@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 — это просто enum, содержащий значение, для сравнения выбранного режима позже в AuthenticationGuard.

Мой app.module.ts добавляет модуль следующим образом:

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

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]);
}

Это отлично работает при использовании защиты с маршрутами и свойством canActivate. Но как только я ввожу его в какую-то другую службу (внутри другого модуля), я получаю эту ошибку:

Ошибка: недопустимый поставщик для NgModule «AuthenticationModule» — разрешены только экземпляры Provider и Type, получено: [?undefined?, ...] в SyntaxError.ZoneAwareError

Итак, мой основной вопрос:

  • Это способ сделать ngModule настраиваемым?
  • И что решит проблему выше?

Сборка с использованием Angular 2 и angular-cli (бета-версия 25)


person eav    schedule 02.02.2017    source источник


Ответы (1)


Как насчет сохранения настройки в специальной переменной и использования фабрики для ее внедрения?

let authModeSetting: AuthMode;

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

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

    return AuthenticationModule;
  }

}
person smnbbrv    schedule 02.02.2017
comment
Хорошая идея. Пробовал, но не работает из-за этой ошибки: Error encountered resolving symbol values statically. Calling function 'AuthenticationModule', function calls are not supported. Consider replacing the function or lambda with a reference to an exported function, resolving symbol AppModule in app.module.ts, resolving symbol AppModule in app.module.ts - person eav; 02.02.2017
comment
Calling function 'AuthenticationModule' звучит странно, где это вызывается как функция? - person smnbbrv; 02.02.2017
comment
Только в imports из AppModule, как видно из кода вопроса: AuthenticationModule.forRoot(AuthMode.OAuthLocalStorage) Может из-за AOT (по умолчанию в ng serve из angular-cli)? github.com/angular/angular-cli/issues/3674 - person eav; 02.02.2017