angular2のチュートリアルでフォームを作ってみた。
教えられた通りに入力するともちろん動作するのだけど、それぞれのキーワードが何を指定しているのかよく分からなかったので調べた事をまとめる。
簡単なフォームを作ってみる
FORM_DIRECTIVESをインポート
import {FORM_DIRECTIVES} from 'angular2/angular2';
フォームを定義
@Component({
selector: 'demo-form'
})
@View({
directives: [FORM_DIRECTIVES],
template: `
<form #f="form">
</form>
`
})
export class DemoForm {}
フォームを構成する要素を定義
<div>
<label for="id">id</label>
<input type="text" ng-control="id">
</div>
<div>
<label for="name">name</label>
<input type="text" ng-control="name">
</div>
submitボタンを設置
- <form #f="form">
+ <form #f="form" (submit)="onSubmit(f)">
...
<button type="submit" class="btn btn-default">Submit</button>
...
export class DemoForm {
+ onSubmit(f){}
}
バリデーションをつけてみる
- <input type="text" ...>
+ <input type="text" ... required>
- <button type="submit" ...>Submit</button>
+ <button type="submit" ... [disabled]="!f.valid">Submit</button>
完成。とりあえず動く。
しかし仕組みがさっぱり分からない
FORM_DIRECTIVESって何?
フォームを利用するにはディレクティブをインポートする必要がある。
- ng-control
- ng-control-group
- ng-form
- ng-model 他。
FORM_DIRECTIVESを使うとこれらをまとめて指定した事になる。
f="form"って何?
#
はテンプレート内での変数宣言。
formだけでなく他のタグでも使用可能。
<!--"input1"という変数名をつける-->
<input type="text" #input1>
<!--DOMを変数として参照-->
{{#input1.value}}
つまり<form>
を変数f
として参照する事を意味している。
<form #f="form">
="form"って何?
=
の右側にクラス名を書くと、そのクラスのエイリアスが生成される。
angularのソースを参照するとngControlGroup
がform
という名前で利用可能になっている。
angular/angular forms/directives/ng_control_group.ts
@Directive({
selector: '[ng-control-group]',
...
exportAs: 'form'
="form"
と書くとformのエイリアスが生成され、自動的にng-form
が設定される。
ControlGroup???
サンプルで作った簡単フォームは以下のディレクティブで構成される。
ng-form
|-- ng-control
|-- ng-control
|-- ...
テンプレートの定義に置き換えるとこうなる。
<form #f="form">
<input ng-control="id">
<input ng-control="name">
...
各ディレクティブはこのようなイメージでクラスを生成する。
// 実際のメソッドを調べた訳でないので、あくまでイメージ
var f = new ControlGrup();
f.add(new Control('id'));
f.add(new Control('name'));
ng-form(=ControlGroup)がいろいろ動いてフォームの機能を実現しているらしい。
ng-formは何をしてくれるのか?
- 子要素(ng-control)を見つける
- フォームのデータ管理
- バリデーション など。
submitイベントを持っているのでこのような指定ができる。
<form #f="form" (submit)="onSubmit(f)">
引数で渡したf
はng-form自身を示す。
.valueを見ると子要素をkey:valueのペアで持っている。
onSubmit(f){
console.log(f.value);
// console : Object {id:"1", name:"test"}
}
またバリデーションを実行しているため、結果を参照できる。
<button type="submit" ... [disabled]="!f.valid">Submit</button>
チュートリアルだけでは何がどう動いているのか、さっぱり分からなかった...。