AngularDartのアーキテクチャ概要を理解する ※執筆途中

AngularDartの公式ドキュメントの下記「アーキテクチャ概要」を理解するためにまとめてみました
>公式ドキュメント：https://angulardart.dev/guide/architecture

公式ドキュメントにあるアーキテクチャの図解は下記になります。
こちらを一つずつまとめていきます
>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326131/235512c2-1e32-776a-a05f-27c2d1ba16b2.png)

上記構成図の構成要素は下記8つになります。
・モジュール (Modules)
・コンポネント (Components)
・テンプレート (Templates)
・メタデータ (Metadata)
・データ・バインド (Data binding)
・ディレクティブ (Directives)
・サービス (Services)
・依存物注入 (Dependency injection)

##モジュール
モジュールとは、ライブラリやパッケージなどのDartのコンパイルユニットを指します。
>コンパイルユニットとは、Dartファイルにlibraryとかpart directiveを持たないDartファイルのことです。
>またpart directibeとはlibraryを複数ファイルに分割できるものです。
>参考：https://dart.dev/guides/libraries/create-library-packages

Angularアプリは少なくとも1つのモジュールとルートモジュールを持ちます。
モジュールは機能モジュールや、各アプリケーションドメインを扱うまとまったコードブロックであったり、ワークフローだったりします。
最もシンプルなルートモジュール例は下記のような単一のルートコンポーネントクラスを定義します。
また、慣例としてルートコンポーネントの名前はAppComponentと定義します。

```dart:lib/app_component.dart
class AppComponent {}
```

##コンポーネント
コンポーネントとはviewをサポートするアプリケーションロジックになります。
また、コンポーネントクラスにはサポートの為のロジックをクラスで定義します。
また、@lacolacoの記事では下記のように定義しています。
>AngularDartにおけるComponentとは、「軽量」で、「再利用可能」であり、「一つの目的に特化した」UI要素です
参考：[AngularDart入門 第3回 Angular Components](https://qiita.com/lacolaco/items/1e969a20c92b9e3c0a3c)

コンポーネントクラスではプロパティ(メンバ変数)とメソッドのAPIを介してviewをやり取りをします。
下記は公式ドキュメントのサンプルコードになります。

```dart:lib/src/hero_list_component.dart
class HeroListComponent implements OnInit {
  List<Hero> heroes;
  Hero selectedHero;
  final HeroService _heroService;

  HeroListComponent(this._heroService);

  void ngOnInit() async {
    heroes = await _heroService.getAll();
  }

  void selectHero(Hero hero) {
    selectedHero = hero;
  }
}
```

このサンプルコードは公式ドキュメントのチュートリアル抜粋のコードになりますが、実装している内容は下記の通りです。

・HeroListComponentはviewのサポートの為にheroのリストをサービスから取得し、heroesプロパティのリストとして保持します。
・`selectHero()`ではユーザーがリストからヒーローを選択してクリックしたときにselectedHeroプロパティを設定するように定義しています。
・`ngOnInit()`はライフサイクルフックと呼ばれる機能で、ユーザーがアプリ内を移動するとコンポーネントを作成、更新および破棄するものです。
`ngOnInit()`はコンポーネントが呼び出された際に定義されたアクションを初期化/実行します。

>参考：[Lifecycle Hooks](https://angulardart.dev/guide/lifecycle-hooks)

##テンプレート
コンポーネントのViewを定義する役割がテンプレートになります。
テンプレートはHTML形式でどのようにコンポーネントに表現するかを定義します。
公式のチュートリアルで提供している下記テンプレートの例では通常のHTMLになりますが、いくつか異なる点があります。

```html:lib/src/hero_list_component.html
<h2>Hero List</h2>

<p><i>Pick a hero from the list</i></p>
<ul>
  <li *ngFor="let hero of heroes" (click)="selectHero(hero)">
    {{hero.name}}
  </li>
</ul>

<hero-detail *ngIf="selectedHero != null" [hero]="selectedHero"></hero-detail>
```

テンプレートは、`<h2>`や`<p>`などの典型的なHTML要素を使用します。
また、`*ngFor`、`{{hero.name}}`、`(click)`、`[hero]`、`<hero-detail>`などのAngularのテンプレート構文を使用するコードも含まれています。
テンプレートの最後の行にある`<hero-detail>`タグは新しいコンポーネントである`HeroDetailComponent`を表すカスタム要素です。
新しいコンポーネント(コードは表示されていません)は、HeroListComponentによって表示されたリストからユーザーが選択したヒーローに関する内容を表示します。
HeroDetailComponentは、HeroListComponentの子クラスになります。

カスタムコンポーネントであるHeroDetailComponentは、上記コードのように、同じレイアウトでカスタムコンポーネントとネイティブHTMLを混在させてることができます。

子クラスのレイヤー図は下記の通りです。
>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326131/1cd852d0-ea6e-8462-66cf-e701ddf920e9.png)

##メタデータ
メタデータはAngularにクラスの処理方法を伝える役割になります。
hero_list_component.dartのHeroListComponentクラスのコードをみるとそれは単なるクラスであり、Angularに伝えるまではコンポーネントではありません。
HeroListComponentがコンポーネントであることをAngularに伝えるには、クラスにメタデータであることを伝える必要があり、Dartでは@Componentの注釈を使用してメタデータを定義します。

下記コード例ではHeroListComponentのメタデータを定義しています。
@Componentアノテーションを使用してHeroListComponentクラスをコンポーネントクラスとして識別させます。

```dart:lib/src/hero_list_component.dart
@Component(
  selector: 'hero-list',
  templateUrl: 'hero_list_component.html',
  directives: [coreDirectives, formDirectives, HeroDetailComponent],
  providers: [ClassProvider(HeroService)],
)
class HeroListComponent implements OnInit {
  // ···
}
```

また、@Componentアノテーションは、Angularがコンポーネントとそのviewを作成して表示するために必要な情報を提供するパラメーターを受け入れます。
下記で定義されているメタデータのパラメータを説明していきます。

###１、selector
このパラメータはCSSセレクタで親HTMLで`<hero-list>`タグで指定した際に、このコンポーネントのインスタンスを作成して挿入するようにAngularに伝えます。
例えば、アプリのHTMLに`<hero-list></hero-list>`が含まれている場合、Angularはこのタグの間にHeroListComponentのviewのインスタンスを挿入します。

###２、templateUrl
このパラメータはコンポーネントのHTMLテンプレートをAngularに伝える役割があり、相対パスで定義します。

###３、directives
このパラメータはこのテンプレートに必要なコンポーネントやディレクティブのリストを定義します。
`<hero-detail>`など、テンプレートに表示されるアプリタグをAngularで処理するには、ディレクティブリストでタグの対応するコンポーネントを宣言する必要があります。
また、ディレクティブとは記事で下記のように定義されています。
>Angularの「ディレクティブ」は、HTMLタグの属性と似た記法で指定して、その要素を操作する仕組みです。
>
>参考：[Webページ要素を操作できる「Angular」のディレクティブを自作してみよう](https://codezine.jp/article/detail/11488)

coreDirectivesを定義すると`*ngFor`のようなAngularのテンプレート構文を使用できます。
>参考：[core_directives.dart](https://github.com/dart-lang/angular/blob/67d1bd06a152956e315d443042ef9da646e57552/angular/lib/src/common/directives/core_directives.dart)

###４、providers
このパラメータはコンポーネントが必要とするサービスのための依存性注入プロバイダーのリストを定義します。
これは、表示されるヒーローのリストを取得できるように、コンポーネントのコンストラクタがHeroServiceを必要とすることをAngularに伝える1つの方法です。
依存性注入については後ほど取り扱います。



※執筆途中

##参考
下記を参考にさせて頂き、大変読みやすく、理解しやすかったです。

[Angularのアーキテクチャ概説](https://www.cresc.co.jp/tech/java/Google_Angular/guide/architecture/index.html)
[AngularDart入門 第3回 Angular Components](https://qiita.com/lacolaco/items/1e969a20c92b9e3c0a3c)
[Webページ要素を操作できる「Angular」のディレクティブを自作してみよう](https://codezine.jp/article/detail/11488)