“Unobtrusive JavaScriptである”ということ

突然ですが、最近AngularJSを触り始めました。

AngularJSはJavaScriptのフレームワークでMVCモデルを…とそんな前置きはさておき、O’REILLYの「AngularJSアプリケーション開発ガイド」の中に”Unobtrusive JavaScript”という言葉が出てきたので自分なりに軽く考えてみました。

Unobtrusive JavaScript。そのまま訳すると「控えめなJavaScript」とか「目立ちすぎないJavaScript」とかそんな感じすかね。言葉自体はだいぶ昔からあるみたいです。
Unobtrusive JavaScriptについて説明しているサイトがあったのでリンクを張っておきます。

端的に書けば”ページの構造と動作は分離する”なんですかね。(もっとたくさんの事も書いているけれど。)
CSSでHTMLの構造とスタイル(デザインやレイアウト)を分離したのと同様にHTMLの構造とJavaScriptも分離しましょう、っと。

Wikipediaと似たような例で行くと、JavaScriptだと以下のようなところ。

<input type="text" id="text1" onchange="validate()" /><br>

というのがある場合、以下のようになる。

<div>
  <input type="text" id="text1" />
</div>
window.onload = function() {
  document.getElementById('text1').onchange = validate;
};
var validate = function(event) {
  // 処理
};

onchange属性内はJavaScriptとして扱われるので、onchange部分を画面が読み込まれた時のイベント処理で設定。こうすることでHTMLの構造と処理を分離できます。
これだとvalidateがGlobal Scopeだから…等々ももちろん気を付ける必要はありますが、昔ながらの構造/処理ごっちゃごちゃよりかは可読性も品質もあがります。

ただ、こういったことを毎回するのは結構面倒。そういったことを解決するのがフレームワークであってAngularJSもそのうちの1つ。

AngularJSの場合は以下のようになります。

<div ng-controller="TextController">
  <input type="text" id="text1" hg-change="validate()" />
</div>
var TextController = function($scope) {
  $scope.validate = function(event) {
    // 処理
  };
};

「inputタグにng-changeみたいな振る舞いはってるじゃない?」と思われるかもしれませんが、hg-changeで指定したメソッドを呼び出すという宣言であってこれ自体がJavaScriptを実行するもの(動作)ではありません。最終的に動作を決めるのはController(ng-controllerで指定した内容)及びAngularJSであり、ブラウザ間の差異もAngularJSにより解決することでどのブラウザでも正しく動作します。
あと、呼び出せる関数はそのスコープ内でありGlobal Scopeでないところも重要です。

ng-controller等々を書かなきゃいけないのが面倒かもしれませんが、たくさんの画面を作る場合はこの小さい面倒を払った方が後々の大きい面倒を招かなくて済みます。少ない画面や少ないコンポーネントで済むぐらいであればAngularJSを使う必要性はないですしね。(ただ、その場合でも”Unobtrustive JavaScript”の考え方は持っていたいところです。)

年明け一発目でダラダラ書いてしまいましたが、AngularJSネタも少しずつ上げていこうと思います。

余談ですが、Unobtrusive JavaScript的な考え方ってPureMVCのライブラリであるFabricationも同じような感じですよね。

では。