記事の内容をrc.4に対応しました
動作サンプルについてはまだBeta版のままなのでご了承ください
(2016/08/04)
Angular2(rc.4)の使い方について簡潔にまとめてみました
細かい部分は省くので、公式サイトやQiita内に素晴らしい記事があるので
そちらを参考にしてください
インストール
npm install @angular/common@2.0.0-rc.4 @angular/compiler@2.0.0-rc.4 @angular/core@2.0.0-rc.4 @angular/platform-browser@2.0.0-rc.4 @angular/platform-browser-dynamic@2.0.0-rc.4
rc版から細かい単位でパッケージが分割されるようになったので、必要なものをインストールします
その他、下記のパッケージにも依存しているのでインストールします
npm install core-js@2.4.0 rxjs@5.0.0-beta.6 zone.js@0.6.12
コンパイル用のパッケージとかは必要に応じてインストールしてください
一応、下記リポジトリにQuickStartを作ってあるのでお試しください(リポジトリのものはrc.1です汗)
手軽に試したい場合は、Plunkerもオススメです
使い方
アプリケーションの起動
ES6のモジュール読み込みでbootstrapとルートコンポーネントを読み込み
bootstrap関数にルートコンポーネントを渡します
import {bootstrap} from '@angular/platform-browser-dynamic';
import {App} from './app';
bootstrap(App, [])
.catch(err => console.error(err));
import {Component} from 'angular2/core'
@Component({
selector: 'my-app',
template: `
<div>
<h2>Hello World</h2>
</div>
`
})
export class App {
}
<body>
<my-app>
loading...
</my-app>
</body>
@ComponentはDecorators構文といってclassなどに付加情報を設定するものです
上記ではselectorとtemplateという情報を付与しています
selectorはquerySelectorなどに渡すCSSセレクタと同じものです
CSSセレクタにマッチするタグの中にアプリケーションが展開されます
例えば、selector: 'body'
とするとbodyタグの中に展開されることになります
templateはHTMLテンプレートです
この内容がCSSセレクタにマッチしたタグの中に展開されます
templateUrlとすると外部のテンプレートを設定することも可能です
バインディング
単方向バインディング
モデルからビューへの反映です
<h2>{{title}}</h2>
上記のようにすると、クラスに定義されたtitleプロパティの内容が反映されます
双方向バインディング
<input type="text" [(ngModel)]="title">
上記のようにすると、inputタグ等で入力した値がクラスに定義されたプロパティに反映されます
inputタグに入力した値がモデルに反映され、h2タグの中身も変わることが確認できると思います
イベントバインディング
下記のようにすると、clickなどのイベント発火時に関数を呼び出すことができます
@Component({
selector: 'my-app',
template: `
<div>
<button (click)="onClick()">Click Me</button>
</div>
`
})
export class App {
private title: string = 'Hello World';
private onClick(): void {
alert('Clicked!!');
}
}
他にもタグの属性値にバインディングすることもできますが
公式サイトを参考にするとすぐに理解できると思いますので見てみてください
子コンポーネント
コンポーネントが子コンポーネントを扱うにはComponent Decoratorでdirectivesを設定し
templateに子コンポーネントで定義したCSSセレクタ(タグ)を追加します
@Component({
selector: 'my-app',
template: `
<div>
<h2>Parent Component</h2>
<child-component></child-component>
</div>
`,
directives: [ChildComponent]
})
制御構文
ngIf、ngFor、ngSwitchなどがあります(ngSwitchの説明は省略)
ngIf
タグに*ngIf="条件式"
と記述すると、条件を満たす時にタグが出力されます
条件を満たさない時はタグ自体が出力されません
条件式の記述方法はJavaScriptと同様です
また、下記のように<ng-container>
タグを使用すると無駄なタグを出力しなくなります
<ng-container *ngIf="...">
<h1>test</h1> <!-- ここだけ出力される -->
</ng-container>
出力しても問題ない場合は普通に<div>
タグ等で囲めば大丈夫です
ngFor
<ul>
<li *ngFor="let alphabet of alphabets; let idx = index">[{{idx}}]{{alphabet}}</li>
</ul>
上記のように、タグに*ngFor="let 変数名 of Iterableな変数"
と記述すると繰り返しタグが出力されます
またlet 変数名 = index
と記述すると、現在のインデックスが取得できます
DI(Dependency Injection)
いわゆる「依存性の注入」ってやつです
私がAngular2で一番良くできていると思っているのがこれです
注入される側
HelloServiceというクラスのインスタンスが注入されるとします
下記のように普通にクラスを定義します
export class HelloService {
public hello(): string {
return 'Hello Angular2!!';
}
}
注入する側
Component Decoratorのprovidersに注入するクラス(Provider)を指定し
classのconstructorの引数で受け取るようにします
@Component({
selector: 'my-app',
template: `
<div>
<h2>{{hello}}</h2>
</div>
`,
providers: [HelloService]
})
export class App {
private hello: string;
constructor(private helloService: HelloService) {
this.hello = helloService.hello();
}
}
上記のようにすると、Appクラスがインスタンス化される時に
自動的にHelloServiceが注入されるようになります
インジェクトチェーン
この注入の仕組みですが、JavaScriptのprototypeチェーンに似ています
自身のprovidersにProviderがなければ、親のコンポーネントを探しに、親のコンポーネントになければ、さらに上に・・という感じに
そしてこのインジェクトチェーンの頂点はbootstrap関数の第2引数です
つまり、ここで指定されたProviderはどのコンポーネントでも使用できるということになります
bootstrap(App, [HelloService]);
上記で説明した以外にもDIについてはいろいろあるのですが
下記の記事が非常にわかりやすいので参考にしてみてください
@Input
親のコンポーネントから子コンポーネントに値を渡したい時があると思います
そんな時に使うのが@Inputです
@Inputはコンポーネントに属性を定義するAPIです
export class ChildComponent {
@Input() id: string;
@Input('userName') name: string;
}
上記のように@Inputで定義したものが属性として扱えます
属性名と内部の名前を変えたい場合は@Input('属性名')
とすると変えることが可能です
親コンポーネントで下記のようにします
@Component({
selector: 'my-app',
template: `
<div>
<child-component id="0" userName="Alice"></child-component>
<child-component id="1" [userName]="name"></child-component>
</div>
`,
directives: [ChildComponent]
})
export class App {
private name: string = 'Bob';
}
一番目のように値を直接指定して子コンポーネントに渡すこともできますし
二番目のように内部の変数の値を子コンポーネントに渡すことも可能です
また、子コンポーネントに値が渡ってくるタイミングですが
constructorではなくAngular2のライフサイクルのngOnChangesのタイミングなのでご注意を
※2016/04/15訂正 ngOnInitではなくngOnChangesでした
まとめ
長々と書いてきましたが、これだけおさえておけばAngular2を使う時に悩むことはないと思います
@Outputという便利な機能がありますが、今回は省略しました
私はAngular1系をあまり触ってこなかったんですが、Angular2は非常によくできてるFWだと思います
是非お試しください!!