ITの隊長のブログ

ITの隊長のブログです。Rubyを使って仕事しています。最近も色々やっているお(^ω^ = ^ω^)

【Angular2】Formを動的に扱うコードを書いてみた

スポンサードリンク

ここまで来るのに時間かかったよ!!!

github.com

コードは全部こっちにあります。コミットログを追ったら情報わかるかも。もしわからないなら質問ください。ただ私も初心者に近いので答えられる範囲ですが(^^;

まずやりたいこととして、jQueryみたいにdomを動的に作ってviewに流し込みしたり、イベントを用意してバリデーションとかしたかった。

AngularJS1.xでは、そういうことを実装したことがなかったので、どうやってやればいいんだろ?って悩んでいたのね。

んで、色々試行錯誤したり、チュートリアルを試してみたりなどやっていくと。

情報少なすぎ、チュートリアル少なすぎワロタ。壁にぶち当たり。泣いた(´;ω;`)ブワッ

このままjQueryに戻って実装してやろうかなと思った。

しかしダメだ・・・! お前はまた4000行以上のコードを書きたいのか。。。!メンテしたいのか・・・!と、思い踏みとどまった。

思いだけでは解決しなかった。我慢ならなかったので、ぐぐって本を購入しました。 www.ng-book.com

洋書なので、もちろんよめませんでした(´;ω;`)ブワッ

んで、最近賢くなったと聞いたGoogle翻訳を使ってみました。

すると、これがすごく有能。使いながら読むとコードを理解しながら英語の勉強にもなった。Googleすげえぇええええ!!!

で、読んだ内容はFormの基礎。簡単にまとめる。

Angular2のFormは、入力フォームにFormControlを使い、FormGroupでグルーピングする。

使い方ざっくり

  • moduleで、FormsModuleimportしてね。
  • FormControlはこうやって使う => <input type="text" name="name" ngModel>
  • FormGroupは、<form #f="ngForm" (ngSubmit)="onSubmit(f.value)">...</form>
    • onSubmitのメソッドを用意したら、FormGroupにセットされているFormControlの値にアクセスすることができる

#f="ngForm"とかngModelとかなにこれ?と思うかもしれないが、どうやらFormsModuleを呼ぶと暗黙的に値がセットされるらしい。

初期値渡したいの。どうすればいい?

  1. FormBuilderを使った方法があります。

当初はこれが細かい設定の方法だと思っていましたが、どうやらこのクラスもFormGroupFormControlのためのシンタックスシュガーっぽい。

本当に細かくしたいならnew FormControl()とかnew FormGroup()のように、インスタンス化から自分で手続きしなけいけない。

さて、FormBuilderの話に戻る。こちらも使い方ざっくり

  • さっきのFormsModuleに、ReactiveFormsModuleも追加でimport
  • 使いたいComponentで、FormBuilderをDIする
  • FormBuilderのメソッドに、groupがあるので、KeyValueでFormControlになる値を渡してあげる。
private myForm: FormGroup;
constructor(formBuilder: FormBuilder) {
  this.myForm = formBuilder.group({
    'myName': ['初期値だお']
  })
}
  • view側では、<form [formGroup]="myForm">...</form>にすること。このmyFormComponentのメンバー名と同じしないとダメよ!
  • また、<input>では、属性に[formControl]="myForm.controls['myName']"を使う。

これでおk。初期値が入るはず。

このFormBuilderは、ValidateやCustom Validateでも利用できるので、こっちの方を使ったほうがいいかも知れないです。

Validateは?

はい。書きます。

バリデーションは、FormControlの第二引数にセットすればおk.FormBuilderを使っているのなら、こう書けば良い。

import { FormGroup, FormControl, FormBuilder, Validators} from '@angular/forms';
// ...
private myForm: FormGroup;
constructor(formBuilder: FormBuilder) {
  this.myForm = formBuilder.group({
    'myName': ['初期値だお', Validator.required] // <- 第2引数に追加
  })
}

こうすると、requried(必須)のバリデーションが動いてくれる。

また、エラーも表示したいよね? view側でこう書いて。

<div *ngIf="myForm.controls['myName'].hasError('required')"
  class="ui error message">myName is required</div>

複数バリデートしたい場合は? 絶対あるよねー。

第2引数に配列で渡せばいいでしょ?って思うかもしれないがそれはできない。

なので、Validator.compose()というメソッドを使って値を合成(?)して渡す。

private myForm: FormGroup;
constructor(formBuilder: FormBuilder) {
  this.myForm = formBuilder.group({
    'myName': ['初期値だお', Validator.compose([
      Validator.required,     // 必須
      Validators.minLength(5) // 5文字以上
    ])]
  })
}

view側もさっきと同様に追加してね。これでよし。

全部書こうと思ったけど、疲れたからまた今度追記する。Githubのログを追ったら一応わかるはずだけど。

残り

  • Custom Validator
  • Watch Value Changes
  • 本には乗っていなかった自分で試したやつ
    • Enter keyを無効にしたい
    • Datepickerとの組み合わせ
    • 動的にFormを追加

本の感想

すごくわかりやすいよ!!

英語なので、ストレス溜まっていたけど、Google翻訳のおかげで今ならすっと入ってきます。英語が綺麗なのもあるのかな。

まだFormの章しか読んでいないので、ちゃんとオススメはできませんが、基礎はしっかり、後半はチャットアプリデモの作り方みたいな章もあるのですごく楽しみです。

ちと高めですが、勉強したい人はぜひー。 www.ng-book.com