Angular入門 5日目
社内ツールをバックエンドをGo(goa)で、フロントエンドをAngularで作ることにした。
5日目。 ちょっと忙しくてあまり時間が取れなかった。
金曜日にやったこと
バリデーション
inputタグにpatternという属性を指定すると良いみたい。ngModelでバインディングしておく必要があるかもしれない。
<input type="text" id="code" name="code" [(ngModel)]="project.code" #code="ngModel" pattern="PJ-[0-9]{6}">
こんな感じで正規表現が使える。
バリデーションのメッセージ
invalidな時にエラーメッセージを出すには以下のようにする。
<div [hidden]="code.valid"> <span class="help is-danger"> codeはPJ-で始まる6桁の数字です </span> </div>
hiddenはCSSで display: none
を付けるようなので、他のCSSのスタイルと競合しないように注意する必要がある。
もしかしたら ngIf
を使った方が良いかもしれない。
フォームの見た目
inputタグなどを赤くしたいような時には、規定のCSSクラスを定義する。
例えはinvalidな時には、 ng-invalid
というクラスが付与されるので、form.cssなどを作って置いてそこに必要なスタイルを書いてHTMLから参照する。
.ng-invalid { border-color: #F00; }
app.component.css に書けば良いのでは?と思ってたけど、違った。cssはcomponentごとに独立しているらしい。
Angular入門 4日目
社内ツールをバックエンドをGo(goa)で、フロントエンドをAngularで作ることにした。
4日目。
今日やったこと
ルーティング
そもそもルーティングの設計がおかしかったのと、謎の思い込みがあって、関係ないところで時間をつぶしていた。
// 抜粋 const appRoutes: Routes = [ { path: 'projects', component: ProjectsComponent }, { path: 'projects/new', component: ProjectDetailComponent }, { path: 'projects/:id', component: ProjectDetailComponent }, ];
この状態で /projects/new
にアクセスすると、route parameter(と言うらしい)のidはnewになる。当たり前なんだけど、整数値の時だけ /projects/:id
に振り分けられるという思い込みをしていた。
それに、Serviceでデータを取得する箇所でエラーが出ていたのに、ルーティングでのエラーだと勘違いしていた。
新規用ページの作成
編集ページを流用して、idが取れないときには空のオブジェクトを作ってComponentで使うようにした。
ようやく、一覧、新規、編集、削除とできた。
rxjs
Observable について深く気にしてなかったけど、rxjsと関係があるらしい。
使いこなせると、多分このコードも上手く直せるんだろうな。
getProject() { let id = +this.route.snapshot.params['id']; if (id > 0) { this.projectService.getProject(id) .subscribe(project => this.project = project as Project); } else { this.project = new Project(); } }
雑感
細かいところで色々わかってないところはあるものの、CRUDを実装したので、ダミーデータで一応動くようになった。
あとは、バリデーションとそれのメッセージ通知辺りかな。
Angular入門 3日目
社内ツールをバックエンドをGo(goa)で、フロントエンドをAngularで作ることにした。
3日目。
今日やったこと
Observerableの対応
PromiseからObserverableに変えたら上手くいってなかった件、単純にデータの取得が間違っていただけだった。
getProjects(): Observable<Project[]> { return this.http.get(this.projectURL) .map(res => res.json().data as Project[]); }
res.json().data
の data
が抜けていた。
チュートリアルの後半にsearch関係のがあって、関係ないと思って読んでなかったけど、ちゃんと書いてあった。 チュートリアルよく読もう…
Typescriptのキャストについて調べた
Typescript: cast an object to other type. How? And instanceof or typeof? - acdcjunior’s
as
で良いっぽい。
編集、削除の機能追加
チュートリアルを参考に、update, deleteを実装した。
気になったのが、リストから個別に削除するのはまぁ簡単なんだけど、そのあとリストを更新しなくて良いんだろうか?
まぁでもブラウザ上は存在している(と思われる)データが実はなかったというのを知るタイミングの問題かな。
ルーティングがよくわからん
Rails のルーティングを参考に設定したいんだけど、
// 抜粋 const appRoutes: Routes = [ { path: 'projects', component: ProjectsComponent }, { path: 'projects/new', component: ProjectDetailComponent }, { path: 'projects/:id', component: ProjectDetailComponent }, ];
サブディレクトリのところが上手くいかない。:idの方が優先されるのかなぁ。
Angular2のRouting, Formsの簡単なサンプル。ついでにFlux。(2.0) - Qiita
この辺参考に明日やってみよう。
雑感
コードを書くときはTypescriptなので、型が間違ってるとかはちゃんとチェックしてくれるんだけど、as
とかのキャストを使ったりするところでは、実際動かすと上手くいかない。
キャストする時はその辺注意した方が良さそう。
Angular入門 2日目
社内ツールをバックエンドをGo(goa)で、フロントエンドをAngularで作ることにした。
2日目。
今日やったこと
編集画面のフォーム周り
モデルとフォームをバインディングする辺りのコードを書いた。
「これが噂に聞いていた双方向バインディングかぁぁぁぁ!!!」とちょっと感動した。
formタグのところだけ別のComponentにして切り出してみて、データの渡し方(@Inputあたり)を確認した。でも、なんかめんどくさくなっただけかも。
モデルの修正
管理すべきデータを間違えていたので、モデルを作り直した。
Typescriptの型チェックのおかげで、ダミーデータが誤っているのもすぐ分かって快適だ。
Serviceを作った
チュートリアルを参考にしてServiceを作ってそこからダミーデータを返すようにした。
HTTP - ts - TUTORIAL
PromiseをServiceとComponentで受け渡ししてるんだけど、直接、特定の型の配列を返してはいけないんだろうか?
あと、Observerableの方が良いらしい?
Angular2のHttpモジュールを眺めてベストプラクティスを考える - Qiita
これを見てPromiseを使わないようにやろうとしてるとこで、上手くいかなくて時間切れ。なんか勘違いしてるっぽい。
次回はこの辺対応して、新規と削除までの一通りの操作できるようにしたい。
VSCodeに乗り換えた
Angularをやるにあたって、VimでTypescriptとかの開発用の設定をしないと行けないと思っていたけど、せっかくなので、何度か試しては辞めていたVSCodeを使ってみることにした。
今日でまだ2日目だけど。
VSCodeを以前試して使わなかった理由として、複雑なウィンドウ分割ができなかったからだけど、今回そこは諦めることにした。(VimではT字に分割することが多い)
アップデートしたらメニューとかが日本語になっていた。ローカライズのプラグイン入れた覚えはないので、本体で対応したんだと思う。
プラグインはGo関連は以前入れていたので、AngularやTypescript関連をとりあえず追加した。
ターミナルがなんか使いやすくなっている感じ。
ng serve
しておいて、エラーがあったらすぐ気付けるので良い。
コード補完も特に問題ないし、関数の簡単なヘルプが出てくれたりするのも良い。
たぶんここまで書いたことは、Vimでもプラグインを活用すれば、充分できることだと思う。ただ、その辺設定するのに疲れてしまったのも本音だ。
そういえば、メジャーなエディタにはVimのキーバインドが使える系のプラグインがあるが、完全に再現できないだろうし、入れないことにしてる。
だけど、ErgoDoxにして、カーソルキーをfn+hjklで使えるようにしたからスムーズに移行できたのかもしれない。
Angular入門 1日目
社内ツールをバックエンドをGo(goa)で、フロントエンドをAngularで作ることにした。
今日やったこと
angular-cliのインストール
とりあえずこれがあれば良いっぽい。
CSSフレームワークの選定
「css フレームワーク」とかでググって、見た感じが良さそうで、使いやすそうなやつを探した。
Bulma: a modern CSS framework based on Flexbox というのを使うことにした。
css周りは5年ぶりくらい。flexboxというやつでレイアウト組めるらしく、なんかすげ〜と思った。
画面作成
とりあえずバックエンドとの連携は置いといて、画面を作り込んで行くことにした。
- プロジェクトの一覧画面
- プロジェクトの編集画面
を作った。ほとんど見た目の調整。
ページ毎に
ng g component hoge
でcomponentを作る- HTMLを編集
- routerの設定に追加
って感じでやってるけど、これで良いのかわからん。
新規作成画面は、編集画面に空のオブジェクトを渡せば良いかな。 たぶん、routerで新規用のパスを設定して、そこの初期値で空のオブジェクトを指定すれば良いんではないかという気がする。
それともformの部分を切り出して、新規と編集はそれを利用するcomponentにする、みたいなのが良いだろうか。
雑感
Angularのフルスタック感がRailsのそれと近い感じがして、初めは拒否反応があったんだけど、しばらく触ってみると面白くなってきた。
久しぶりのjavascriptと思っていたけど、Typescriptはまたなんか違う感じだった。型があるので、安心感がある。
Goと過ごした1年間
今日で仕事納めだったので、振り返っておく。
今年はGoのコードをたくさん書けた1年間だったと思う。
- サービス基盤の一部をGoで開発した
- 新人研修の主な言語としてGoを教えた
- 既存のRailsで作ったサイトのリプレースをGoでやった
- 社内で使うツールをGoで作っている
- goaを触り始めた
サービス基盤の開発
去年の後半から始まって、今年の3月末にリリースが完了した。モバイルアプリ用のpush配信周りの実装を担当したが、APNSに関連してHTTP/2を使ったやりとりとかも経験できて面白かった。
周囲の特に上司の理解と協力もあって、社内でGoを使ったプロジェクトの実績が作れたのは大きかった。 前例ができたからか、以降「Goでやります」と言いやすくなったし、リプレースのプロジェクトにもつながったと思う。
新人研修
自分のチームに配属になったのが6月からで、それからGoを教えて、社内で使うツールを作ってもらった。とりあえず年末を目処にそこそこ使える形のあるものはできたので良かったと思う。
研修が始まる前には、プログラミング自体を経験したことがない、という人にGoを教材としてプログラミングを教えることが正解なのかどうか、かなり悩んだ。
現状Goでの、プログラミングが未経験という人に向けた情報が少ないと思う。なので、参考になる事例も見当たらず、本当に研修を全うできるのか?という不安があった。
正直言うと(本人にも伝えたが)途中で辛くなって、Railsでなんかパッと動くやつを課題に設定した方が、研修としては面白かったのでは?とか思ったこともあって、モチベーションが低かった時もあった。
最終的には、そこそこのコードは普通に書けるねという感じになってきているし、良かったと思う。
研修をしてわかったことは、新人でもGoで書いたコードは普通に質が高いというか、誰が書いても同じようなコードになるのが不思議だなと。瑣末なところはもちろん色々あるんだけど、おかしなコードを書いているってことは感じたことがない。
リプレース
Railsで作ったサイトをリプレースした。もともと小規模なサイトだったので、Goで一から作ろうということになって、3サイトをリプレースした。
リリースしてからリソースのグラフをたまに見ているが、Railsで起きていた徐々にメモリ消費が増えていくということもなく、安定している。
サーバーのスペックを落としても充分さばけると思うし、お客さんの費用に直結するので、省リソースでサイトが運用できるというのは良いことだと思う。
ついでに社内のサービスと接続するためのAPIクライアントも作れたので、ますますGoでプロジェクトを進めやすくなった。
社内ツールもろもろ
chatops(ってもう死語?)とかその辺でslackのbot作ったりとか、他にも細々としたツールを作っていて、なんか作る時にはGoで作るようにしている。
やっぱりポータビリティというか、コンパイルしてコピーして動くっていう手軽さは大きい。
goa
Goでウェブアプリケーション作るときに、あまり大きな(リフレクションを使うような黒魔術的)フレームワークは採用したくない。でもチーム開発する以上ある程度のルールは必要で、goaを使えばその辺を解消できると思う。
例えば、基本的なバリデーションとか細々した実装がそこそこあってちょっとしんどい、みたいなところがラクできそう。
goa自体はAPIサーバーを前提としていると思うけど、管理画面とかHTMLを返したいし、その辺を独自ジェネレーターとかDSL拡張とかで対応できないか試行錯誤しているところ。
apexと組み合わせてAWS lambdaで動かしたりしたい。
おわりに
特にまとめはない。
Goをやるぞ!と言って実際に実績が積めているのは大変嬉しいことだし、もっと社内でも普及活動をしていこうと思う。