Angular2を使ってみる 5. Counter作り
なにをやってみようか
一通り導入までの勉強はしたので自分でもいじってみようと思う。でも何をいじろうか。
考えたけど、以下の2つを実施することにする。
- fileの再配置(srcとdistの分離)
- buttonを押したらcount upするだけの簡単なcomponentの作成
これらが終わったらRxJSを使うような処理も入れてみたいなあ。今のところこれといって作りたいapplicationがあるわけではないので、どこにたどり着くのかは僕にもわからない。知らない技術の実験的な感じで終わるかも。あ、lessとかstylusと言われているものも使いたい。
環境整理
ではまず環境整理。fileの再配置(srcとdistの分離)をする。
まずindexにある*.jsを削除して、と。./srcにindex.htmlを配置。で、どうしようかな。とりあえず今はこんな感じ。
% tree -I node_modules . ├── Makefile ├── README.md ├── app.component.ts ├── app.module.ts ├── hello-world.component.ts ├── index.ts ├── package.json ├── src │ └── index.html └── tsconfig.json
うーん。typescriptのfileをsrcに移動しよう。これで準備は出来た。あとはbuildのparameterを変えて、dist/以下に配置されるようにする。Makefileからmake build
で呼び出すつもりなので、dirがなければ作るようにそちらに書き込み。
あ。typescriptのcompileという行程があった。こっちは出力先指定できるかな。
-outDir DIRECTORY Redirect output structure to the directory.
あったあった。
npm ERR! angular2@1.0.0 tsc: `tsc -p ./src --outDir ./dist` npm ERR! Exit status 2 npm ERR! npm ERR! Failed at the angular2@1.0.0 tsc script 'tsc -p ./src --outDir ./dist'.
怒られた。駄目なの?
いやいけそうな気がする。
ああ違った。fileを再配置した時点でcompileが通らなくなっている。tsconfig.jsonをいじってあげないといけないんだ、たぶん。
filesやoptionをいじってみた。これでどうだろう。
無事通った。
これでmake cleanすると、
% tree -I node_modules . ├── Makefile ├── README.md ├── package.json ├── src │ ├── app.component.ts │ ├── app.module.ts │ ├── hello-world.component.ts │ ├── index.html │ └── index.ts ├── tmp └── tsconfig.json
make buildすると、
% tree -I node_modules . ├── Makefile ├── README.md ├── build │ ├── app.component.js │ ├── app.module.js │ ├── hello-world.component.js │ └── index.js ├── dist │ ├── bundle.js │ └── index.html ├── package.json ├── src │ ├── app.component.ts │ ├── app.module.ts │ ├── hello-world.component.ts │ ├── index.html │ └── index.ts └── tsconfig.json
という感じに生成されるようになった。
……htmlは最初からdistでもいい気がしてきた。ちなみにmake buildする都度にdistやbuildはrm -dされるお気楽仕様。
componentの追加
次にcount upのcomponentを追加しよう。いやNgModuleだっけ?
今回の目標としては<my-counter></my-counter>のようなものを入れ込んで、まずはそこに数値を表示させるまで。その次にformとしてのbuttonをいれて、その次にeventを組み込み、最後に<my-counter>に反映させるというところまで……結構手順あるな。
さてどうすればいいんだろう。app.module.tsに追加してもいいけど作る物としては全然別物でhello worldと依存関係があるわけでもないからmoduleとしては分けておこうか?
いや違うか。ここにBrowserModuleがある以上ここがbrowser処理の最初のはず。だからここのbootstrapとdeclarationsにcomponentを追加する感じか。
counter.component.ts
まずはcounter.component.tsを作ってみる。ほぼhello-world.component.tsと同じ。selectorとtemplateを少し変えてみた。
import { Component } from '@angular/core'; @Component({ selector: 'my-counter', template: ` <h2>Counter:0</h2> ` }) export class CounterComponent {}
app.module.ts
次にapp.module.tsにCounterCompoerntを入れ込む。
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { AppComponent } from './app.component'; import { HelloWorldComponent } from './hello-world.component'; import { CounterComponent } from './counter.component'; @NgModule({ imports: [ BrowserModule ], declarations: [ AppComponent, HelloWorldComponent, CounterComponent ], bootstrap: [ AppComponent, CounterComponent ] }) export class AppModule {}
app.component.ts
これでいいかと思ったけどいや<my-counter>をまだどこにも埋め込めてないよ。どこだっけ。調べてみたらapp.component.tsだった。
ここに適当に入れ込む。
import { Component } from '@angular/core'; @Component({ selector: 'my-app', template: ` <hello-world></hello-world> <my-counter></my-counter> ` }) export class AppComponent {}
試してみる
これで何はともあれ表示はされるはず。browserで確認。された。よかよか。
次はformの入れ込みかなあ。じわじわ進めよう。
formの追加?
さてこっからだ。何をどうしたらいいのかさっぱりわからぬ。
でもcomponentの構造上、一番上のcomponentにまずは全部の要素を入れ込んでみればいいと思う。今回はcounter.component.tsか。ここに必要な要素をとりあえずdomで入れ込む。
import { Component } from '@angular/core'; @Component({ selector: 'my-counter', template: ` <div> <h2>Counter:0</h2> <button>Increment</button> <button>Decrement</button> </div> ` }) export class CounterComponent {}
こんな感じ。ちゃんと反映されることを確認。
auto build
……しかしそろそろ、手元で変更したら自動でbuildしてほしいなあと思ったりもする。
あ、emacs使っていてmakefileも使ってるならcompile呼び出せるじゃん。M-x compileとM-x recompileでよしとしよう。
いやいやまてまて。なんかあるだろ。……まあいいか。別にこれで困ることもないし。
eventの追加
さてbuttonを追加したのだから次はeventを追加しよう。どうやって。
たぶんbuttonのcomponentを作ってやるんだろうけど。
方法EventEmitterなるものがある、と。それでもいけそうだけど初っぱなからapi referenceだけ参照して組むのも怖いのでtutorialとかでそもそもそういうのないのだろうか。
あー。これ参考にすればそのまま組めそう。でも公式の説明もみたい。
angular 2 basic counter · GitHub
あ、そのまんまやりたいことをやっているところがあった。ほうほう。export classの中にmethodを入れているのかこれは。で、{{}}で囲った部分には変数を埋め込める、と。
import { Component } from '@angular/core'; @Component({ selector: 'my-counter', template: ` <div> <h2>Counter:{{counter}}</h2> <button (click)="increment()">Increment</button> <button (click)="decrement()">Decrement</button> </div> ` }) export class CounterComponent { public counter : number = 0; increment(){ this.counter += 1; } decrement(){ this.counter -= 1; } }
おーすげえ。できた。何これ早い……。eventもへったくれもなかった……。domとlogicの融合がここまで便利とは思わなかった。びっくりだわ。すげえ。楽。すげえ(やかましい)。
今までだったら頑張ってdivのidを定義して取得して書き換えてとか結構書く必要あっただろうに。
ああそうか。このeventのところでapiたたくとかの機能も入れられるのか。うん。なるほど。楽しくなってきた。
ここまでをgithubにcommit。v0.0.2というtag。
一応調べておく
今回使ったclick eventの部分のreference。
Angular 2 Events · Learn Angular 2
読んでの通りだった。
次の予定
次はさっきのpageのをまねしてtodo listを入れてみようかな。 ここを参考にして、User Registration and Login Exampleとかもいいかも。
ああそれとそろそろcssやbootstrapも入れ込んでみたい。RxJSも使ってみたいし。
当面の課題はこんなところかなあ。