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


AngularDartの公式ドキュメントの下記「アーキテクチャ概要」を理解するためにまとめてみました

公式ドキュメント:https://angulardart.dev/guide/architecture

公式ドキュメントにあるアーキテクチャの図解は下記になります。
こちらを一つずつまとめていきます

上記構成図の構成要素は下記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と定義します。

lib/app_component.dart
class AppComponent {}

コンポーネント

コンポーネントとはviewをサポートするアプリケーションロジックになります。
また、コンポーネントクラスにはサポートの為のロジックをクラスで定義します。
また、@lacolacoの記事では下記のように定義しています。

AngularDartにおけるComponentとは、「軽量」で、「再利用可能」であり、「一つの目的に特化した」UI要素です
参考:AngularDart入門 第3回 Angular Components

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

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

テンプレート

コンポーネントのViewを定義する役割がテンプレートになります。
テンプレートは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を混在させてることができます。

子クラスのレイヤー図は下記の通りです。

メタデータ

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

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

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を作成して表示するために必要な情報を提供するパラメーターを受け入れます。
下記で定義されているメタデータのパラメータを説明していきます。

1、selector

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

2、templateUrl

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

3、directives

このパラメータはこのテンプレートに必要なコンポーネントやディレクティブのリストを定義します。
<hero-detail>など、テンプレートに表示されるアプリタグをAngularで処理するには、ディレクティブリストでタグの対応するコンポーネントを宣言する必要があります。
また、ディレクティブとは記事で下記のように定義されています。

Angularの「ディレクティブ」は、HTMLタグの属性と似た記法で指定して、その要素を操作する仕組みです。

参考:Webページ要素を操作できる「Angular」のディレクティブを自作してみよう

coreDirectivesを定義すると*ngForのようなAngularのテンプレート構文を使用できます。

参考:core_directives.dart

4、providers

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

※執筆途中

参考

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

Angularのアーキテクチャ概説
AngularDart入門 第3回 Angular Components
Webページ要素を操作できる「Angular」のディレクティブを自作してみよう