53 votes

Passer les données de configuration en utilisant forRoot

J'essaie de faire passer des données de configuration dans une bibliothèque personnalisée en Angular.

Dans l'application des utilisateurs ils transmettront des données de configuration à ma bibliothèque en utilisant la méthode suivante forRoot

// Import custom library
import { SampleModule, SampleService } from 'custom-library';
...

// User provides their config
const CustomConfig = {
  url: 'some_value',
  key: 'some_value',
  secret: 'some_value',
  API: 'some_value'
  version: 'some_value'
};

@NgModule({
  declarations: [...],
  imports: [
    // User config passed in here
    SampleModule.forRoot(CustomConfig),
    ...
  ],
  providers: [
    SampleService
  ]
})
export class AppModule {}

Dans ma bibliothèque personnalisée et plus particulièrement le index.ts Je peux accéder aux données de configuration :

import { NgModule, ModuleWithProviders } from '@angular/core';
import { SampleService } from './src/sample.service';
...

@NgModule({
  imports: [
    CommonModule
  ],
  declarations: [...],
  exports: [...]
})
export class SampleModule {
  static forRoot(config: CustomConfig): ModuleWithProviders {
    // User config get logged here
    console.log(config);
    return {
      ngModule: SampleModule,
      providers: [SampleService]
    };
  }
}

Ma question est la suivante : comment rendre les données de configuration disponibles dans la bibliothèque personnalisée ? SampleService

Actuellement SampleService contient les éléments suivants :

@Injectable()
export class SampleService {

  foo: any;

  constructor() {
    this.foo = ThirdParyAPI(/* I need the config object here */);
  }

  Fetch(itemType:string): Promise<any> {
    return this.foo.get(itemType);
  } 
}

J'ai lu les documents sur Prestataires Toutefois, l forRoot L'exemple est assez minimal et ne semble pas couvrir mon cas d'utilisation.

0 votes

Avez-vous pu passer une carte à votre configuration personnalisée ? quelque chose comme ceci myMap : Map<string, string[]> ; J'essaie de passer une carte mais cela ne fonctionne pas si j'active l'AOT (ng serve --AOT).

96voto

Günter Zöchbauer Points 21340

Vous y êtes presque, il suffit de fournir les deux SampleService y config dans votre module comme ci-dessous :

export class SampleModule {
  static forRoot(config: CustomConfig): ModuleWithProviders<SampleModule> {
    // User config get logged here
    console.log(config);
    return {
      ngModule: SampleModule,
      providers: [SampleService, {provide: 'config', useValue: config}]
    };
  }
}

@Injectable()
export class SampleService {

  foo: string;

  constructor(@Inject('config') private config:CustomConfig) {
    this.foo = ThirdParyAPI( config );
  }
}

Mise à jour :

Depuis Angular 7 ModuleWithProviders est générique, il a donc besoin de ModuleWithProviders<SampleService>

3 votes

Excellente réponse ! Je l'utilise habituellement mais à la place de string Je préfère utiliser OpaqueToken(InjectionToken)

2 votes

Merci :). Je trouve OpaqueToken trop lourd à expliquer, mais vous avez raison bien sûr. C'est la méthode préférée. En fait, c'est maintenant InjectionToken angular.io/docs/ts/latest/api/core/index/

2 votes

Non en utilisant InjectionToken illustre en fait la flexibilité de l'injecteur. Il démontre également l'utilisation de l @Inject(dep) qui est très utile.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X