web-dev-qa-db-ja.com

NullInjectorError:ElementRefのプロバイダーがありません

プロジェクトのモジュールに内部ディレクティブを作成しました(Angular 8 + Material Design)。次のtutoと公式ドキュメント。

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

}

わかりました。しかし、外部ライブラリを作成してディレクティブ(コンポーネント、サービスなど)を移動すると、次のエラーが発生します。

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

ng new fop-common -Sに続いてng g library fop-commonから作成されたlibは、libフォルダーをクリーンアップして、module.tsを保持し、ディレクティブ/コンポーネント/サービスを追加しています...

Button-confirmation.module.ts

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

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

Fop-common.module.tsは次のようになります

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

そして私のプロジェクトでは、それをインポートします

  imports: [
...
    FopCommonModule
  ],

Libのインストールには、ローカルの方法(npmを使用しないプライベートプロジェクト)を使用しました:npm install ../fop-common/dist/fop-common --save

私はすでにインターフェイスとパイプが機能しているので、グローバルに機能していますが、ElementRefの問題がありますが、この場合は何も見つかりませんでした(symlinkパラメーターを使用した<8の古い解決策は除きますが、コース外では機能しません)。

どんな助けでも感謝します。前もって感謝します。

3
Killan

解決策は見つかりませんでした。

Libを作成する代わりに、プロジェクトにコード(libコンテキストではなく)を戻しましたが、両方のgit repoを分離して再利用しています。

したがって、トリックは、内部に「lib」リポジトリを含む/ src/libsubfolderを作成するポストインストールスクリプトを追加し(git clone)、メインプロジェクト.gitignoreを編集してこのlibsubfolderを追加することで、「機能する」トリックソリューションが得られます。

より簡単にするために、tsconfig.jsonを編集してパス設定を追加し、メインプロジェクトを介したすべてのインポート用にlibsubfolderをマップしました。

そのため、同じリポジトリ(angular/projectsフォルダー)内のすべてのプロジェクトを回避し、メンテナンスと再利用が可能で、簡単に配置でき、それぞれに独自のリポジトリがあります。だから私にとっては大丈夫です。

助けてくれた人に感謝します。

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

ライブラリのリンクではなく、アプリケーションのtsconfig(ライブラリにリンクする場所)にpathsマッピングを作成します。

1
Ashwani Kumar

これは、compilerOptionsのtsconfig.tsに追加します。

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