ご注意 perev。:この記事を理解するには、Angularの基本的な知識(コンポーネントとは何か、単純なSPAアプリケーションの作成方法など)が必要です。 このトピックに精通していない場合は、最初にSPAアプリケーションを作成する例に慣れることをお勧めします。 ドキュメント。
エントリー
@NgModule
は、Angular 2に追加されたデコレータです 。 公式ドキュメントから、 @NgModule
はクラスをAngularモジュールとして定義することに@NgModule
ます。 角度モジュールは、アプリケーションを相互に作用し、最終的に完全なアプリケーションを表す部分(モジュール)に分解するのに役立ちます。 つまり、モジュールは、アプリケーションの機能の一部のパッケージまたはカプセル化です。 モジュールは再利用できるように設計できます。 特定のアプリケーション実装に依存しません。
アプリケーションに遅延ロードを実装する場合は、アプリケーションの設計時に角度モジュールの概念を使用する必要があることに注意してください 。
ルートモジュール
Angularアプリケーションのルートモジュールは、エントリポイントとして使用されます。 モジュールは、 @NgModule
で装飾されたクラスです。 モジュールの標準コードを見てみましょう(たとえば、 ng new project-name
を使用して新しいプロジェクトを作成すると、次のAppModule
がAppModule
ます:
// app.module.ts @NgModule({ imports: [BrowserModule], declarations: [AppComponent], bootstrap: [AppComponent], }) export class AppModule { }
@NgModule
デコレータは、JavaScriptオブジェクトを引数として使用します。
declarations
プロパティで、モジュールに含まれるコンポーネントを宣言します。 この場合、これはAppComponent
コンポーネントです。 複数のコンポーネントが存在する可能性があり、それらはコンマで宣言されます(通常のJavaScript配列のように)。
declarations: [AppComponent]
コンポーネントにmy-app
セレクターがあるとします。 HTMLテンプレートに<my-app></my-app>
を記述すると、アプリケーションはコンポーネントをロードします。
DOMでのコンポーネントの読み込みはどうですか?
AppModule
は、DOMにAppComponent
コンポーネントを埋め込む必要があることをブラウザに伝えます。
AppModule
はどのようにしてコンポーネントをDOMに追加しますか?
AppModule
は、Angularユーティリティモジュールをインポートします。
BrowserModule
は、ブラウザでのアプリケーションの操作を担当します。 本質的に、これは、コード( AppComponent
)およびブラウザーAPIと対話するサービスです。 BrowserModule
には、コンポーネントテンプレートで使用できるNgIf
およびNgFor
も含まれています。
AppModule
は、データ、そのプレゼンテーション、ブラウザ間のブリッジとして機能します。
アプリケーション構築
Angularアプリケーションの使用はmain.ts
ファイルから始まります。詳細についてはマニュアルをお読みください 。
// main.ts import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { AppModule } from './app.module'; platformBrowserDynamic().bootstrapModule(AppModule);
上記の例では、 動的コンパイル(JIT-Just In Time)を使用しています。 ただし、AngularではAOTコンパイル(Ahead of Time)を実装できますが、これは広範なトピックであり、別の記事で説明します。
宣言(告知)
アプリケーションでは、独自のコンポーネント、ディレクティブ、およびパイプを作成します。 追加する機能(コンポーネント、ディレクティブ、パイプ)をアプリケーションに伝えるには、 @NgModule
デコレーターの引数であるオブジェクトのdeclarations
プロパティにリストします。
// app.module.ts @NgModule({ imports: [BrowserModule], declarations: [ AppComponent, VehicleListComponent, VehicleSelectionDirective, VehicleSortingPipe ], bootstrap: [AppComponent], }) export class AppModule { }
コンポーネントが宣言された後、コンポーネントの説明に示されているセレクタを介して他のコンポーネント内で使用できます。
インポートおよびネストされたモジュール
BrowserModule
をAppModule
にインポートしますCommonModule
、Angularで使用可能なNgIf
およびNgFor
ディレクティブを含むNgIf
をNgFor
します。 CommonModule
をインポートするCommonModule
、アプリケーション全体でこのモジュールに実装されている機能にアクセスできます。
しかし、 ngModel
やhttp
など、フォームの実装に必要な機能を使用したい場合はどうでしょうか? ソリューションは簡単です-これらのモジュールをAppModule
にインポートするだけです:
// app.module.ts @NgModule({ imports: [ BrowserModule, FormsModule, HttpModule ], declarations: [ AppComponent, VehicleListComponent, VehicleSelectionDirective, VehicleSortingPipe ], bootstrap: [AppComponent], }) export class AppModule { }
FormsModule
モジュールをインポートした後、コンポーネントテンプレートでngModel
を使用できます。 また、 HttpModule
使用すると、HTTPプロトコルを介してデータを送受信できます。
プロバイダー
多くの場合、アプリケーションには、いくつかの(またはすべての)コンポーネントで使用したいサービスがあります。 すべてのコンポーネントにサービスへのアクセスを提供する方法は? 角度モジュールを使用します。
これを行うには、プロバイダーをルートモジュール(この例ではAppModule
に追加する必要があります。 Angularでは、依存関係の追加はDependency Incetionパターンを使用して実装されます。 プロバイダーをAppModule
ルートモジュールに追加すると、アプリケーションのどこからでも利用できるようになります。
プロバイダーの最もわかりやすい例として、これはアプリケーションのあらゆる場所で必要です-承認サービス(ロガーサービス)。 アプリケーションにはアクティブユーザーのリストも表示する必要があります。そのため、 HttpModule
モジュールのおかげで使用できるhttp
を使用してAPIにアクセスし、アクティブユーザーのリストを取得するVehicleService
が必要です。 以前にアプリケーションにインポートしました。
// logger.service.ts import { Injectable } from '@angular/core'; @Injectable() export class LoggerService { log = (msg: string) => { console.log(msg); }; }
// vehicle.service.ts import { Injectable } from '@angular/core'; @Injectable() export class VehicleService { getVehicles = () => [ { id: 1, name: 'X-Wing Fighter' }, { id: 2, name: 'Tie Fighter' }, { id: 3, name: 'Y-Wing Fighter' } ]; }
これらのサービスをAppModule
のルートモジュールに導入すると、アプリケーションコンポーネントで利用できるようになります。
// app.module.ts @NgModule({ imports: [BrowserModule, FormsModule, HttpModule], declarations: [ AppComponent, VehicleListComponent, VehicleSelectionDirective, VehicleSortingPipe ], providers: [ LoggerService, VehicleService, UserProfileService ], bootstrap: [AppComponent], }) export class AppModule { }
それがどのように機能するかを説明しましょう。 コンポーネントのコンストラクターにプロバイダーオブジェクトの作成を追加しました。次のようになります。
// some.component.ts @Component({ selector: 'some-component', template: '<h1>Some component {{ service.data }}</h1>' styleUrls: ['./path/to/style.css'] }) export class SomeComponent implements OnInit{ constructor (private service: Service){} // // }
コンポーネントのインスタンスを作成すると(たとえば、コンポーネントが使用されているページを開くとき)、 providers
プロパティで説明されていると同時にサービスオブジェクトが作成され(上記のapp.module.tsのリストを参照)、Angularは親コンポーネントでこのサービスのクラスの検索を開始します。 なぜなら コンポーネントでプロバイダーを宣言しなかったため、最終的にAngularはAppModule
ルートモジュールでこのサービスを見つけます。 Angularのプロバイダーはシングルトンパターンを実装しているため、アプリケーションでサービスクラスのインスタンスを1つしか作成できないことに注意してください。 この場合、サービスインスタンスが既にどこかで作成されている場合、コンポーネントはそれを使用し、そうでない場合は、サービスオブジェクトを作成します。
おわりに
私の意見では、プロバイダーはAngularモジュラーシステムの最も興味深い複雑な概念の1つです。 プロバイダー(サービス)を使用するための基本的なルールは、ルートモジュールでサービスのインスタンスを作成し、要求に応じてこのインスタンスをアプリケーションの他の部分(コンポーネント)に転送することです。
-ロシア語を話すAngularコミュニティの電報 。