初心者がAngularでSPAのテストページを作成するまで

#今回のゴール

- ローカル環境でのAngularを使ってページを閲覧する。
- 複数のコンポーネントを用意して画面遷移をSPAで実現する。

この2点が達成できるようにしていきたいと思います。
まずはあまりハードルが高くないように"Hello World"の表示コンポーネントと、"Good Bay World"の表示コンポーネントを行き来できるようにしたいと思います。

※なお初心者且つ参考情報はネットの流し読みなため、正確性には欠けますが悪しからず。

#事前準備
まずはAngularを使えるような環境にする所まで行きます。
なお事前にNode.jsやgitなどのインストールは済んでいる前提です。
###Anguralインストール
``` JavaScript:Angular-CLI　インストール
npm install -g angular-cli
```

Node.jsを入れていればnpmが入っているはず。

そうすりゃよしなにインストールしてくれました。
※書籍やもっとしっかりとした参考ページを見る時はバージョン指定など気を付けて。

その他の便利ツールやEDIなどは今回使用しません。

###プロジェクトのひな型を作成

適当にテスト用のディレクトリを切り、そこでAngularのひな型プロジェクトを作成します。

``` JavaScript:ひな型プロジェクト作成
ng new test-ng
```

ここまで来ればあとはビルドすれば一応ページを確認する事ができます。

``` JavaScript:プロジェクトのビルド
cd test-ng
ng server
```
あとは下記にアクセスすると、「App Works」が表示されます。
http://localhost:4200/

わりとちょろでAngularを使う事ができました。
続いて用意したひな型プロジェクトに手を加えて、新コンポーネントの作成とその遷移を同じページ内で行うという事をやっていきたいと思います。

#コンポーネントを編集して表示を変える

ここからはプロジェクトの構成や表示方法を確認しながらゴールに向かってひな型をいじっていきます。

###ひな型の構成を確認する

ひな型プロジェクトが出来たと思うので、その中身をかいつまんで確認していく。
まず作成したプロジェクトの構成を確認したら、srcフォルダに基本的にソースが入ってそうですね。

![Angularフォルダ構成.PNG](https://qiita-image-store.s3.amazonaws.com/0/6164/02daec93-cef8-c2b5-0f9a-b0e05183fe14.png)

ちなみにこのプロジェクトの直下に配置されているファイル達は設定ファイルらしいので、今回は特に触れません。

さらにビルドを実行するとdistフォルダが作成されます。
その内部をWebサーバにデプロイする事で、Webサービスとして公開する事が可能という寸法らしいっす。

これ解説してると大変な事になるので、実際に触ってしまいます。

ぐりぐり探っていくと、srcの配下のappって所にapp.component.tsっていうファイルがあります。
その内部に"app works!"の文字が！！

``` TypeScript:app.component.ts
export class AppComponent {
  title = 'app works!';
}
```

どうやらこのtitleって書いてあるのが、app.component.htmlから呼び出されているようです。
そしてどうやらこのコンポーネント群をルートモジュールと呼ぶらしいです。
※ここから各コンポーネントを呼び出したりして処理を実行させていくと。

``` html:app.component.html
<h1>
  {{title}}
</h1>
```

そしてこのHTMLファイルはビルドの時にメインのHTML（index.html）のスクリプトと指定され、呼び出されているのでしょう。
※めんどくさくなって調べてないです。

```html:index.html
<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>TestWeb</title>
  <base href="/">

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
  <app-root>Loading...</app-root>
</body>
</html>
```

### コンポーネントの内容を変更してみる

と少し脱線しましたが、どうやらAngularのページ表示を変更するにはapp.component.tsファイルを変更すればできそうです。

というわけで最初の目的である「Hello World」の表記に変更してあげてみます。

``` TypeScript:app.component.ts（改修後）
export class AppComponent {
  title = 'Hello World';
}
```

これでまた ng server コマンドを打ってローカル環境にアクセスしてみると、、、
![画面変更後.PNG](https://qiita-image-store.s3.amazonaws.com/0/6164/510750e0-9163-6a1e-61d1-1b767bd1a556.png)

という形で画面描画の修正まで完了しました。

# 新しいコンポーネントを作成する

まずコンポーネントを作成するためには、下記をまとめて作成する必要があります。

- css
- html
- spec.ts
- ts

これらを毎回手で作成するのは面倒なので、ちゃんとコマンドが用意されています。
それは ng g component <新コンポーネント名> なので今回は page01 というコンポーネントを作成してみたいと思います。

```shell-session:新コンポーネント作成
$ ng g component page01

installing component
  create src\app\page01\page01.component.css
  create src\app\page01\page01.component.html
  create src\app\page01\page01.component.spec.ts
  create src\app\page01\page01.component.ts
  update src\app\app.module.ts
```

てな感じでウィーガシャンと新しいコンポーネントが作成されました。

今度はこのコンポーネントを表示させる事で疑似的なページ遷移を実現してみたいと思います。
※本来はコンポーネントを複数用意して行き来させる方がよいかと思いますが、今回はルートモジュールからコンポーネントを呼び出して表示し、その後ルートに戻るという流れだけを実現します。

#モジュール管理設定ファイルにルータ設定を追記する

まずは今回作成したコンポーネントをルータに設定し、切り替えを画面遷移を伴わずに実行できるようにします。
下記ソースのコメント下行のみが編集箇所のはず。。。

```ts:app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';

import { AppComponent } from './app.component';
//新コンポーネントをインポートする。
import { Page01Component } from './page01/page01.component';

//ルータ扱えるようにインポート
import { RouterModule,Routers } from '@angular/router';

//コンポーネントとパスの関連性を追記する。（この時のnextがURLもどきとなって表示される）
export const AppRoutes = [
   {path: "next",component: Page01Component}
]

@NgModule({
  declarations: [
    AppComponent,
    Page01Component
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    //ルータリストをインポート　
    RouterModule.forRoot(AppRoutes)
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
```

これでコンポーネントの切り替えをルータ？を使って実現できるはず！！

あとは各コンポーネントにて、リンク（URLのhrefではなくrouterLinkを使用する）を記載すればOKなはず。

#ルートモジュールのコンポーネントへリンクを記載する

まずデフォルトで表示されるルートモジュールの中に、新コンポーネントへのリンクを作成します。

```html:app.component.html
<h1>
  {{title}}
</h1>
<!-- 新コンポーネントを呼び出すリンクボタンを設置 -->
<button routerLink="/next">NextButton</button>
<!-- 呼び出されたコンポーネントが表示される場所を指定 -->
<router-outlet> </router-outlet>
```

これで新コンポーネントを呼び出すためのボタンが作成され、且つ呼び出された時に表示する領域を設定する事ができました。

![ボタン追加後.PNG](https://qiita-image-store.s3.amazonaws.com/0/6164/01671625-f50f-c39c-5b34-820d8903fac2.png)

このNextButtonを押下すると新コンポーネントを使っての描画が実施されるというすんぽーです。

#新コンポーネントから戻ってこれるようにする。

前章までで、コンポーネントを切り替えて画面の描画を切り替えるというSPAの基本形ができたのですが、実際には戻れないとあまり意味がない（切り替えている感が出ないし目標と違う。。。）ので戻ってこれるように作成したコンポーネントにも手を加えます。

```html:app.component.html
<p>
Good Bay World
</p>
<!-- ルートモジュールのコンポーネントへ戻るボタンを設置 -->
<button routerLink="">BackButton</button>
```

ここまで準備できたら、あとはng serverってばちこーーんして、適当に動作を確認しましょう。

下記が新コンポーネントを使っての描画です。

![コンポーネント切り替え後.PNG](https://qiita-image-store.s3.amazonaws.com/0/6164/417f501b-f109-53ff-7f82-07aaa0f47797.png)

てな感じで表示が切り替わり、URLの所がポートの後/nextが入っています。
これでURL自体は遷移していない事を確認できます。

というわけでBackButtonを押すと元の画面に戻ります。
※新コンポーネントを描画する前になる。

#まとめ的な

以上でコンポーネントを切り替える事で画面遷移を実現するというSPAの基礎みたいな部分を体験できたと思います。

今後はルートモジュールと、コンポーネントの分業などを勉強してもう少しアプリケーションと呼べるものを作っていきたいと思います。

またHTMLテンプレートとか双方向バインドとか単語だけ見つけたので、そのあたりも勉強してまとめておきたいと思います。