web-dev-qa-db-ja.com

Angular X(Xは2+を表す)の子モジュールでAppModuleのコンポーネントを使用する

私はアプリケーションのルートに小さなコンポーネント(LoadingComponent)を作成し、それを(明らかに)AppModuleで宣言しました。このコンポーネントは、アプリケーションの読み込み中に使用され、ファンシーな読み込みアニメーションを表示します。

次に、何かを保存するときに子モジュールで使用したいと思います。しかし、このコンポーネントを別のモジュールで使用したい場合、常にエラーが発生します。

LoadingComponentをAppModuleにエクスポートしました。

import { ButtonsModule } from './buttons/buttons.module';
import { FormsModule } from '@angular/forms';
import { StatusLightsDisplayComponent } from './status-lights-display/status-lights-display.component';
import { StatusLightsContainerComponent } from './status-lights-container/status-lights-container.component';
import { HttpModule } from '@angular/http';
import { ReportsService } from './services/reports.service';
import { BrowserModule } from '@angular/platform-browser';
import { forwardRef, NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { GeneralInformationComponent } from './general-information/general-information.component';
import { TextfieldsComponent } from './textfields/textfields.component';
import { LoadingComponent } from './loading/loading.component';

@NgModule({
  declarations: [
    AppComponent,
    GeneralInformationComponent,
    TextfieldsComponent,
    StatusLightsContainerComponent,
    StatusLightsDisplayComponent,
    LoadingComponent
  ],
  imports: [
    BrowserModule,
    HttpModule,
    FormsModule,
    ButtonsModule
  ],
  exports: [
    LoadingComponent
  ],
  providers: [
    ReportsService
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

LoadingComponentを使用するモジュールはButtonsModuleと呼ばれます。 AppModuleButtonsModuleにインポートしようとしました。しかし、私はエラーを得ています:Unexpected value 'undefined' imported by the module 'ButtonsModule'

これが私のButtonsModuleです:

import { AppModule } from '../app.module';
import { LoadingComponent } from '../loading/loading.component';
import { BottomComponent } from './bottom/bottom.component';
import { CalendarComponent } from './top/calendar/calendar.component';
import { CommonModule } from '@angular/common';
import { ExportService } from '../services/export.service';
import { forwardRef, NgModule } from '@angular/core';
import { FunctionsComponent } from './functions/functions.component';
import { NavArrowsComponent } from './shared/nav-arrows/nav-arrows.component';
import { SaveButtonComponent } from './shared/save-button/save-button.component';
import { TopComponent } from './top/top.component';

@NgModule({
  imports: [
    CommonModule,
    AppModule
  ],
  exports: [
    TopComponent,
    FunctionsComponent,
    BottomComponent
  ],
  declarations: [
    TopComponent,
    BottomComponent,
    FunctionsComponent,
    NavArrowsComponent,
    SaveButtonComponent,
    CalendarComponent
  ],
  providers: [
    ExportService
  ]
})
export class ButtonsModule { }

ここではすでにいくつかの失敗を認識している人もいると思います:)しかし、最後まで読んでください。

ここでのベストプラクティスは、共有モジュールを作成して、これをAppModuleButtonsModuleにインポートすることですが、これは、このような小さなコンポーネントとここでも私の唯一の共有モジュールになります。また、多くのオーバーヘッドが発生します。

私の質問:

  • ここで何か悪いことをしていますか?はいの場合、それは何ですか?
  • 共有モジュールを作成することで、正しい方法はありますか?
  • 私のアプローチが機能しないのはなぜですか?つまり、Angularのフードの下で私のアプローチを禁止しているのはなぜですか、そしてなぜですか?
8
Florian Leitgeb

NgModuleは、アプリケーションを機能のまとまりのあるブロックに整理するのに役立ちます。

すべてのAngular appにはルートモジュールクラスがあります。規則により、ルートモジュールクラスはAppModuleと呼ばれ、app.module.tsという名前のファイルに存在します。

同じモジュールを2回インポートするとどうなりますか?

それは問題じゃない。 3つのモジュールがすべてモジュール 'A'をインポートすると、Angularはモジュール 'A'を1回評価しますが、最初にそれが検出されたときは再度評価されません。

これは、インポートされたモジュールの階層にレベルAが出現する場合に当てはまります。モジュール「B」がモジュール「A」をインポートし、モジュール「C」が「B」をインポートし、モジュール「D」が[C、B、A]をインポートすると、「D」が「C」の評価をトリガーし、評価がトリガーされます「A」を評価する「B」のAngularが「D」の「B」と「A」に到達すると、それらはすでにキャッシュされており、準備ができています。

Angularは循環参照を持つモジュールが好きではないので、モジュール「A」がモジュール「A」をインポートするモジュール「B」をインポートしないようにしてください。

リンク

最後にすべてがMain App Moduleにコンパイルされ、同じモジュールに再度インポートすると、上記の条件が循環依存関係に当てはまります。また、メインモジュールであるため、他のモジュールで使用されるエクスポートはないのが理想的です。

9
Rahul Singh

コンポーネントをまとめるだけのコンポーネントモジュールを作成し、それらをエクスポートして、両方の場所にインポートします。最初はつらいように見えますが、どこで何が使用され、何が拡張されるかを整理するのに役立ちます。

3
httpete