[初心者向け] Angular2からみるJSフレームワーク入門

スクリーンショット 2015-12-26 22.24.00
wordpress.comがReact.jsを使ってリニューアルしたり、Angular2がβ版に辿り着いたりと、2015年末は「JavaScriptフレームワーク」(以下、jsフレームワーク)がホットキーワードでした。
けれど、いきなりJSフレームワークをさわろうと思ったら、何これ、これってどういう概念?JSフレームワークのいうMVCって何?どういう機能がついてるの?と混乱すること間違いなしです。よく私も混乱します。
 
そこで、どうやってコーディングするか、ではなく、どういう機能を具備しているのか、を追っていきたいと思います。

追記20151228:
15分で分かったつもりになるAngular 2 概要/angular2がかなりわかりやすくAngular2についてoverviewしているので、ぜひこちらのスライドを先にご覧下さい。

1. MVC(Model-View-Controller)

JavaScriptフレームワークは、MV*フレームワークとか一昔前は言われておりました。
AngularJSはModel/View/Whatever(その他の何か)だとかいわれ、Backbone.jsはMVVMだ!とか、いやいやAngular2は公式サイトからはMV*の文字は消えた、とかあるのですが、フレームワークの構造を考える時にModel-View-Controllerを追ってみるのは理解を深めるために役立ちます。
 
ですので、ここでは強引にAngular2の機能をModel-View-Controllerに分割して、どんな機能があるのかを見てみます。
Model-View-Controllerに分ける理由は、全てControllerに該当する場所にまとめてプログラミングコードも書けるのですが、それだと保守性が悪くなるので、コードを役割に応じて決めた場所に記述し、分割することによってコードの保守性を高めることが目的です。

Model的機能

Modelの目的は、データのCRUD(Create/Read/Update/Delete)とその加工です。
Angular2では、それに該当するモジュールとして、HTTP_PROVIDERSを提供しています。jQueryでいうと、ajaxですね。次のように記述します。
  

http.get('people.json').observer({next: (value) => this.people = value});

 
上記の例では、getを行っておりますが、post/put/deleteなどといったメソッドがそれぞれ用意されています。
 
また、もちろん、ajax通信を行わなくても、ローカルにjson形式でデータを記載するといったこともできます。Angular2-seedをサンプルとして出しますが、このように記述します。
 
これらの機能により、データを動的に扱うことができます。

View的機能

Viewは想像つきますよね。テンプレートを呼び出したり、もしくはJavaScriptの中でテンプレートを定義したりします。
こんな感じ。

  template: `
    <h2>Todo</h2>
    <span>{{remaining}} of {{todos.length}} remaining</span>
    [ <a href="javascript: false" (click)="archive()">archive</a> ]
    <todo-list [todos]="todos"></todo-list>
    <todo-form (newTask)="addTask($event)"></todo-form>`,

とか、

templateUrl: './components/about/about.html'

とか。
 
また、その中でも、JavaScriptの連想配列を展開してviewをループする*ngForや、条件分岐させる*ngIfなどがあり、テンプレート上でPHPと同じようにいろいろとdomの操作を行うことができます。

Controller的機能

で、これらModelとViewを、Controllerで呼び出し、扱います。Controllerがメインメソッドになります。
Angular2は、Controllerではなく、Componentを用います。例えば、以下のような感じ。

@Component({
  selector: 'http-app',
  viewProviders: [HTTP_PROVIDERS],
  templateUrl: 'people.html'
})

 
ただ、PHPフレームワークのように、どのフォルダにどういう命名規則でファイルを置く、みたいな定義は持っておらず、Angular1の時に「Angular.jsのディレクトリ構成のベストプラクティスを探る」という記事が重宝されるぐらいにいろいろな人が悩んでます。
Angular2での有名ドコロは、Angular2-seedや、angular2-webpack-starterがではじめておりますが、ここらへんはこれからみんなが考えていくところかな、と思っております。
 

2. バインディング

JavaScriptフレームワークは、非同期的な処理を予約・自動処理しておくことができます。例えば、Angular1になりますが、双方向バインディングはこんな感じです。(右側のHello !あたりのフィールドです)
jQueryでこれを実現しようと思ったら、inputにidとかclassとかつけて、その値を常に取得して、<span>とかにその値を反映させる形ですかね。めんどい。
 
で、JavaScriptフレームワークを使うと、それを簡単に実現できます、というのがバインディングです。

単方向バインディング

単方向バインディングは、JavaScriptの変数の値をリアルタイムにViewに反映することができます。なので、何かの処理でその変数の変更が行われたら、自動的にView側にもその変更は反映されます。
「単方向」の理由は、例えば、Viewの反映先が<input type=”text”>だったとして、そのinput側で値を変更しても、JavaScript側には反映されないからです。
 
ちなみに、Angular2で単方向バインディングをしようと思うとこんな感じ。

<input (ngModel)="hero.name" placeholder="name">

双方向バインディング

で、双方向バインディングは、view側の値の変更も反映されますよ、っと。双方向バインディングはこんな感じ。

<input [(ngModel)]="hero.name" placeholder="name">

 
どちらも、JavaScript側では、var hero.nameで操作できます。
使い方は、Angular2の公式サイトをご参照ください。

イベントバインディング

変数だけではなく、イベントもバインディングできます。変更監視とか、クリックとか、そういうユーザの挙動を検知して、処理を行います。dataChangedで変更を検知して、自動保存するとか、そういうことも比較的簡単にできます。

<button type="submit" (click)="archive()" />
<inpu type="text" (dateChanged)="statement()">

 

3. Webコンポーネント

CSSだとグローバル空間を定義するので、そのことにより1のパーツにデザインしたCSSが、2のパーツに影響する、ということがよくあります。そのことによるメリットもあるのですが、パーツを分業でつくった時に予期しない影響によって名前をつけかえるということが度々あったり。
Webコンポーネントによりカプセル化すると、そういうことを防げます。詳しくは、以下のブログで。

Angular 2: Component のスタイル実装と CSS のカプセル化

4. ルーティング

JavaScriptフレームワークでは、旧来通りに表示するhtmlを遷移することも可能なのですが、SPA的な利用ーーDOMの置き換えとurlの書き換えによって擬似的に遷移したように見せかけるルーティングを行うのが一般的です。
詳細は「Angular2のRouterを触ってみる」をご覧ください。
 

5. まとめ

最後、駆け足となりましたが、JSフレームワークってこんな感じでいろいろ機能を具備していて便利なので、ぜひ一度さわってみてください。
それでは、また。

お問い合わせ