web-dev-qa-db-fra.com

NullInjectorError: aucun fournisseur pour ElementRef

J'ai créé une directive interne dans un module de mon projet (Angular 8 + Material Design). Après tuto et doc officiel.

@Directive({
  selector: '[button-confirmation]'
})
export class ButtonConfirmationDirective {

  @Output('bc-confirm')
  confirmAction = new EventEmitter<any>();

  @Input('bc-options')
  options: Option[] = [...];

  constructor(
    private el: ElementRef,
    private confirmationService: ConfirmationService
  ) { }

  @HostListener('mouseup') onMouseUp() {
    this.confirmationService.displayConfirm(this.el, this.options, this.confirmAction);
  }

}

D'accord, c'est du travail. MAIS, lorsque je crée une bibliothèque externe et déplace ma directive (avec des composants, des services, ...), j'ai l'erreur:

ERROR NullInjectorError: "StaticInjectorError(AppModule)[ButtonConfirmationDirective -> ElementRef]: 
  StaticInjectorError(Platform: core)[ButtonConfirmationDirective -> ElementRef]: 
    NullInjectorError: No provider for ElementRef!"

La bibliothèque créée à partir d'un ng new fop-common -S suivi par ng g library fop-common puis j'ai nettoyé mon dossier lib en gardant le module.ts et en ajoutant ma directive/composants/services ...

Le bouton-confirmation.module.ts

@NgModule({
  declarations: [
    ButtonConfirmationComponent,
    ButtonConfirmationDirective
  ],
  imports: [
    CommonModule,

    MatButtonModule,
    MatIconModule,
    MatTooltipModule
  ],
  providers: [
    ConfirmationService,
    DomService
  ],
  exports: [
    ButtonConfirmationComponent,
    ButtonConfirmationDirective
  ],
  entryComponents: [
    ButtonConfirmationComponent
  ]
})
export class ButtonConfirmationModule { }

Le fop-common.module.ts ressemble

@NgModule({
  declarations: [
    JoinPipe
  ],
  imports: [],
  exports: [
    JoinPipe,
    ButtonConfirmationModule
  ]
})
export class FopCommonModule { }

Et dans mon projet, je l'importe

  imports: [
...
    FopCommonModule
  ],

Pour l'installation de la lib j'ai utilisé la voie locale (projet privé sans npm): npm install ../fop-common/dist/fop-common --save

J'ai déjà des interfaces et des tuyaux qui fonctionnent, donc globalement ça fonctionne, mais j'ai juste le problème ElementRef, mais je n'ai rien trouvé dans ce cas (sauf l'ancienne solution pour <8 avec le paramètre symlink, mais ne fonctionnant pas bien sûr).

Toute aide apprécie. Merci d'avance.

3
Killan

Aucune solution trouvée.

J'ai remis le code (seulement, pas le contexte lib) dans le projet au lieu de faire une lib, mais je sépare les deux git repo pour les réutiliser.

L'astuce consiste donc à ajouter un script de post-installation pour créer un/src/libsubfolder avec le dépôt "lib" à l'intérieur (git clone), éditer le projet principal .gitignore pour ajouter ce libsubfolder et vous avez une solution astucieuse "qui fonctionne".

Pour plus de facilité, j'ai édité le fichier tsconfig.json pour ajouter une configuration de chemins pour mapper le sous-dossier libs pour toute importation via le projet principal.

J'évite donc tous les projets à l'intérieur d'un même référentiel (dossier angulaire/projets), je le rend maintenable et réutilisable et facile à mettre en place et chacun a son propre référentiel. Donc ça me va.

Merci pour qui a essayé d'aider.

0
Killan
"paths": {
    "@angular/*": [
        "./node_modules/@angular/*"
    ]
}

Faites le mappage paths dans le tsconfig de l'application (où vous vous liez à la bibliothèque) et non à celui de la bibliothèque.

1
Ashwani Kumar

Vous ajoutez ceci dans tsconfig.ts dans compilerOptions:

  "paths": {
      "@angular/*": [
        "./node_modules/@angular/*"
      ]
    }
1
Chrism