Angular 入門 #1

# この会の進め方

https://angular.io/docs を読み進めていきます

---

# Angular<br />自習のススメ

---

# [angular.io/docs](https://angular.io/docs/ts/latest)

- 公式サイトのドキュメントが充実
- ここ読めばもうAngularマスターです
- 英語 :innocent: 

---

# https://github.com/ng-japan/hands-on

- ng-japan (Angular Japan User Group) が公開しているハンズオン
- 日本語 :muscle: 
- 各自これをやりましょう（完）でいい気も :thinking: 

---

# angular.io/docs を読み進める

---

# デモを動かす

大体のページでブラウザ上ですぐ動かせるデモと、ダウンロードしてローカルで動かせるデモが用意されています

> The code referenced on this page is available as a [live example](https://angular.io/resources/live-examples/architecture/ts/eplnkr.html) / [downloadable example](https://angular.io/resources/zips/architecture/architecture.zip).

- live example (plunkr)
  - ブラウザ上でコードの修正と動作が確認できる便利なやつ
- downloadable example
  - ダウンロードして `npm i && npm start` すれば動く便利なやつ
  - systemjs というAngularしか使ってないんじゃないのというモジュールローダーを使用

---

# 便利ページ

大体わかってきたら

- cheatsheet
    - https://angular.io/docs/ts/latest/guide/cheatsheet.html
- styleguide
    - https://angular.io/docs/ts/latest/guide/style-guide.html

---

# angular-cli

空っぽのAngularプロジェクトを作ってアレコレしたいなら angular-cli がオススメ

- `npm i -g @angular/cli`
- `ng new my-sample`
- webpack などの設定をしなくていい
- ユニットテスト、E2Eテスト環境もついてくる
- もう手でwebpack.config.jsを200行も書いてる時代じゃない :muscle:
- `ng generate component sample` などの生成コマンドが便利
- 詳しくは https://github.com/angular/angular-cli/wiki

---

# angular.io/docs/ts/latest

- 初めの方はスキップします
  - Docs home
  - Quickstart
  - cli quickstart
  - Guide
      - Overview
      - Setup
      - Learning Angular

---

# Architecture Overview

---

# Architecture Overview

![overview2 (1).png](https://qiita-image-store.s3.amazonaws.com/0/59312/17266c4d-96d1-974e-f320-9bcac5d77c79.png)

---

# 要するにMVC(雑)

![overview2.png](https://qiita-image-store.s3.amazonaws.com/0/59312/086de256-288e-3710-725b-ff67c5872710.png)

---

# サンプルコード

https://angular.io/resources/live-examples/architecture/ts/eplnkr.html

Angularアプリの構成をひと通り見てみる

module/component/service ...

---

# Module

![module.png](https://qiita-image-store.s3.amazonaws.com/0/59312/b5e9bd93-7ebf-afcc-6547-776ff80d3df9.png)

- component, serviceなどをまとめてモジュールにできる
- Moduleを他のModuleからimportできる

---
# Module

```:app.module.ts
import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
@NgModule({
  imports:      [ BrowserModule ],
  providers:    [ Logger ],
  declarations: [ AppComponent ],
  exports:      [ AppComponent ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }
```

---
# Module

- `imports`
    - 他もモジュールをインポート
- `providers`
    - InjectableなServiceのインスタンス化
- `declarations`
    - モジュールで使うcomponent, directive, pipe
- `exports`
    - このモジュールをimportしたモジュールで使えるようにするcomponent, directive, pipe
- `bootstrap`
    - rootモジュールの場合に起動するコンポーネント

---

# rootモジュールをbootstrapする

```:main.ts
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';

platformBrowserDynamic().bootstrapModule(AppModule);
```

---

# Module

- Moduleを機能・責務で分割していくのがよさそう
- `imports` で依存関係が明確

---

# [Moduleのlazy load](https://angular.io/docs/ts/latest/guide/router.html#!#asynchronous-routing)

- routingにModuleを指定できる
- jsが分割され遅延ロードされる
- 機能毎にModuleを切って、Routingでまとめられる

```:app-routing.module.ts
const appRoutes: Routes = [
  {
    path: 'admin',
    loadChildren: 'app/admin/admin.module#AdminModule',
  },
  ...
];

@NgModule({
  imports: [ RouterModule.forRoot(appRoutes) ],
  exports: [ RouterModule ]
})
export class AppRoutingModule {}
```

---

# Component

![hero-component.png](https://qiita-image-store.s3.amazonaws.com/0/59312/056cf104-dbe4-b808-f872-40d9c00b4770.png)

---

# Component

```:hero.component.ts
@Component({
  selector:    'app-hero',
  template: `<p>hero is {{hero.name}}</p>`,
  styles: [`
    .hero {
      color: red;
    }
  `]
})
export class HeroComponent {
  hero: Hero;
}
```

---

# Component

- `@Component` デコレーターを付ける
- `selector` このコンポーネントのhtmlタグ
- `template` テンプレート
    - `templateUrl: './hero.component.html'`
- `styles` CSS
    - `styleUrls: ['./hero.component.css']`
    - 配列なので何かいいことができそう？

---

# Component, Template

![template-metadata-component.png](https://qiita-image-store.s3.amazonaws.com/0/59312/650f030f-2a11-6f9e-1651-a196ffa18135.png)

- ComponentとTemplateがデータのやり取りをするのがData Binding

---
# Template Syntax

![databinding.png](https://qiita-image-store.s3.amazonaws.com/0/59312/0742cd04-27ff-8ce1-43e0-72fae21e5fef.png)

```
<li>{{hero.name}}</li>
<hero-detail [hero]="selectedHero"></hero-detail>
<li (click)="selectHero($event)"></li>
<input [(ngModel)]="hero.name">
```

---
# Directive

DOMの属性とかを何かしらするやつ

- Componentも正確にはDirectiveの一種
- よく知らないです :rolling_eyes:

---

# Service

MVCでいうMに当たるやつ

- 特に縛りは無い、実装次第でなんでもできる
- 大体はバックエンドとの通信、状態の管理、クッキーへのアクセスとか？

```:logger.service.ts
export class Logger {
  log(msg: any)   { console.log(msg); }
  error(msg: any) { console.error(msg); }
  warn(msg: any)  { console.warn(msg); }
}
```

---
# ServiceとDI

serviceはDIして使うことが多い

```:logger.service.ts
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';

@Injectable()
export class UserHttpService {
  constructor(private http: Http) { }
  ...
}
```

- `@Injectable()` デコレーター
- それをconstructorの引数に含めて使う

---
# ServiceとDI

```:user.component.ts
@Component({
  template: `<p>{{user.name}}</p>`,
  providers:  [ UserHttpService ]
})
export class UserComponent implements OnInit {
  user: User;
  constructor(private service: UserHttpService) { }

  ngOnInit() {
    this.service.getUser()
      .subscribe(user => this.user = user);
  }
}
```

---
# providers

`providers` に書いたところでインスタンス化される

```:my.module.ts
@NgModule({
  imports:      [ BrowserModule ],
  providers:    [ FooService, BarService ],
  declarations: [ MyComponent ]
})
export class MyModule { }
```

- モジュールであればそのモジュール内でserviceが使える
- Componentとかだとそこだけ
- シングルトンなServiceを作りたいときとかは気をつける
- 詳しくは[公式ドキュメント](https://angular.io/docs/ts/latest/guide/hierarchical-dependency-injection.html)

---

# おわり