Angular のコンセプトを理解する / Angular勉強会 #1

---
## Angular講座の概要（予定）
- 1. Angularのコンセプトを理解する
- 2. Angularの代表的なライブラリを知る
- 3. Angularにおける設計手法を考える

---

## フレームワークを理解する上で大切なこと
フレームワークは、ただのツールではなく、その背景に一貫した「コンセプト」があることが多い。例えば。

- Ruby on Rails: 「設定より規約」 ⇒ 細かいルールを定めるのではなく、最適な設定がビルドインされており、開発者が特別な設定を行うのはそれを破りたいときだけだ
- React: 「宣言的/関数的」 ⇒ 全てのReactコンポーネントは、データを引数にとりレンダリング情報を出力する関数であり、これにより宣言的かつ単一方向のレンダリングを実現している。
- Vue: 「親しみやすい」 ⇒ ReactやAngularと重複する機能が多いが、それらをより簡潔に、簡単に書けるようになっている。

**ツールとしての機能は、ググれば出てくることが多く、またかなり移ろいやすい。**しかし、そのフレームワークの**コンセプトはバージョンを重ねても変わることは少なく**、また各種ライブラリを使う上でも助けになる。

---

## Angularのコンセプトとは
Angularのコンセプトは、一言で言えば「大規模設計の扱いやすさ」といえる。そしてそれは以下の3つのメインコンセプトにより担保される。

1. モジュール
2. コンポーネントとバインディング
3. サービス依存性の注入（DI）

これらのコンセプトを使いこなすことがAngularを最大限に活かすための必要条件と言ってよいし、逆にこれらが不要だ、重たいと感じる場合はReactやVueのほうが向いている可能性が高い。

以下、一つずつ確認していく。

---

## Angularのコンセプト①: モジュール
AngularはJavascript（ES2015）で定義されているモジュールとは独立した`NgModule`というモジュール体型をもつ。`NgModule`はアプリケーションの機能やビューの単位を表し、またそれらを結びつける役割をもつ。

またモジュールは自作のものだけではなく、外部のライブラリもモジュールとして参照することができる。

全てのAngularアプリケーションは、 `AppModule` というモジュールを持ち、アプリケーション内で必要となるモジュールは全てこの `AppModule` に含まれる必要がある。つまり**モジュール同士の依存関係をすべて明示的に指定することがAngularアプリケーションでは求められる**。

これは、プロセスを重たくしがちな側面もあるが、モジュールの再利用性やルール上の制約を管理する上で非常に助けとなる。まさにエンタープライズな設計を行いやすい側面と言える。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/447106/34d573c9-2609-f2a8-c96f-0f76b7b35838.png)


---
## Angularのコンセプト②: コンポーネントとテンプレート
コンポーネントとは、Angular内で唯一ビューを定義できる要素である。構成要素は大きく分けて２つあり、HTMLテンプレートやCSSなどのレンダリングを表すものと、そのビューに表示するデータや表示要素を取得したり加工するロジックを表すクラスである。

ただし、Angular内での主体はクラスの方であり、そのクラスにHTMLテンプレートやスタイルを紐付ける形をとる。
（その紐付けにはTypescriptのデコレータを利用する）

AngularにおけるHTMLテンプレートは、通常のHTMLにAngular独自の拡張を加えたものとなり、クラス内のデータやロジックをバインディングを通じてやり取りする。

---

## Angularのコンセプト②: コンポーネントとテンプレート - バインディングによる紐付け

コンポーネント内で、テンプレートの要素をバインディングによって紐付けるのが、Angularの大きな特徴である。バインディングには、イベントバインディングとプロパティバインディングが存在する。

### イベントバインディング
ユーザーのアクションに応じてアプリケーションのデータを更新する、`ビュー → クラス` 方向のやり取り。一般的にはメソッドをユーザーアクションに対してバインディングする形で行う

### プロパティバインディング
システム内の状態変更をビューに対して反映する、 `クラス → ビュー` 方向のやり取り。一般的には、クラスプロパティやGetterメソッドの戻り値を、表示部に対してバインディングする形で行う


また、バインディングの際の値を加工する `pipe` という仕組みも存在する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/447106/f49955a8-7579-cd25-485f-a80f6dd81bb5.png)

---

Angularのコンセプト③: サービスの依存性注入（DI）

ビューに依存しないデータやロジックは、再利用性からもメンテナンス性からも特定のビューとは独立した領域で保持される必要がある。そういったものを保持するのが「サービス」となる。

サービスクラスをコンポーネントや他のサービスに紐付ける際には、単純にコンポーネントから参照を行うのではなく、依存性の注入（Dependency Injection:DI）を用いる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/447106/404d9db5-5ab0-c3c6-d621-ef8a2da9d150.png)


---

## 依存性の注入: DI とは
DIとはもともとはJavaなどのサーバーサイドの分野でよく用いられてきた、**疎結合を保ったまま依存関係を構築する**手法である。

DIを実現する仕組みをDIコンテナといい、Angularにもその仕組は組み込まれている。主な挙動としては以下のようになる。

1. サービスを利用するクラス側が、どのサービスが必要かを記述する。
2. DIコンテナにサービスを登録する
3. DIコンテナが起動時に依存性を解決し、生成したサービスをクラスに注入する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/447106/841c6217-fd90-fd82-dc91-1c68c759e5c3.png)

---

## Angularのコンセプト
Angularのコンセプトは、エンタープライズを見据えた大規模設計の行いやすさである。

AngularはJavascriptのそれとは独立した**独自のモジュール構造を持ち、システムの構造を明示的に記述する**。そしてそれらのモジュール群を、ビューを管理するコンポーネントとロジックを管理するサービスに分離することにより疎結合な設計を担保し、**DIを用いて疎結合を保ったまま依存性を解決**する。ビューは**Angularにより拡張されたHTMLをテンプレート**とし、イベントバインディングとプロパティバインディングという**双方向のバインディングで、クラスロジックと接続**される。