見た目は Bootstrapなのに動きは AngularJSなサイトを作るには

JavaScript

レスポンシブ・デザインやモダンなUIコントロールを取り入れた Webサイトを構築する基礎として定番になっている Twitter Bootstrapを AngularJSと一緒に使う方法を紹介する。

Bootstrapが提供するもの

その1: あたりさわりのない見た目とレスポンシブな表示を提供するスタイルシート

Bootstrapのスタイルシートは、横方向12分割のグリッドでページをレイアウトしつつ画面の大きさによって配分をコントロールできるマルチデバイス向け表示システムと、構成要素の今風な見た目を提供する。デザイナ抜きで動いている開発チームにとっては「とりあえず Bootstrapベースで作っておけば今風の見た目になる」ため極めて有難い存在。

<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/latest/css/bootstrap.min.css">

その2: モダンな Webアプリケーションによく必要とされる様々な UIコンポーネント

HTMLで標準提供されていないがよく必要となるインタラクティブなUIコンポーネント群。これは先程のスタイルシートに加え、jQueryを使った DOM操作を行う JavaScriptで実現されている。問題は、AngularJSのアーキテクチャと相性が悪いこと。

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js">
<script src="//netdna.bootstrapcdn.com/bootstrap/latest/js/bootstrap.min.js">

Bootstrapを使って設置されたドロップダウン

上記でいうところのその2にあたる UIコンポーネントの一例としてドロップダウンを挙げる。マウスでクリックするとドロップダウンメニューが開く。

AngularJSは導入されておらず Bootstrapのみの時、HTMLはこのようになる。

ローカルな HTMLファイルでも動作するよう、CDNのURLは http://..で表記している

<html lang="ja">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/latest/css/bootstrap.min.css">
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
    <script src="http://netdna.bootstrapcdn.com/bootstrap/latest/js/bootstrap.min.js"></script>
  </head>
  <body>
    <div class="container">
      <h1>ドロップダウンのテスト</h1>
      <div class="dropdown">
        <button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown">
          ドロップダウン
          <span class="caret"></span>
        </button>
        <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1">
          <li role="presentation"><a role="menuitem" tabindex="-1" href="#">アクション1</a></li>
          <li role="presentation"><a role="menuitem" tabindex="-1" href="#">アクション2</a></li>
          <li role="presentation"><a role="menuitem" tabindex="-1" href="#">アクション3</a></li>
          <li role="presentation" class="divider"></li>
          <li role="presentation"><a role="menuitem" tabindex="-1" href="#">その他</a></li>
        </ul>
      </div>
    </div>
  </body>
</html>

混ぜるな危険

AngularJSでアプリケーションを開発する場合も、既に基礎として普及している Bootstrapをベースとして使いたいケースは多い。しかし AngularJSはその設計コンセプト上、DOMの直接操作と相性が悪いため AngularJSを用いるHTML5アプリケーションでは(まさにそういう動作をする)bootstrap(.min).jsをロードするべきではない。ではどうするか。試しに bootstrap(.min).js(と、ついでに jQuery)をロードしている script要素を単純に削ってみた。

スクリプトを削ってもスタイルシートは生かしてあるため、ページが表示された瞬間の見た目は変わりないが・・・

_人人人人人人人人人人_
> やっぱり動かない <
 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y ̄

デスヨネー。というわけで何か要る。

AngularJSと Bootstrapを使ったドロップダウン

Bootstrapと AngularJSを一緒に使うには AngularJS側の拡張モジュールである UI Bootstrapを用いる。具体的には、bootstrap(.min).jsのかわりに angular-ui-bootstrap-tpls(.min).jsをロードし、アプリケーション・モジュールに "ui.bootstrap" をインジェクトする(太字部分に注目)。

<html lang="ja" ng-app="MyApp">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/latest/css/bootstrap.min.css">
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js"></script>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.10.0/ui-bootstrap-tpls.min.js"></script>
    <script language="javascript">
      angular.module("MyApp", ["ui.bootstrap"]);
    </script>
  </head>
  <body>
    <!-- この中身は変更なし -->
  </body>
</html>

これにより AngularJS側で 「元の」Bootstrapと同じような動作をするように面倒を見てくれるようになる。また、多少のおまけも付いてくる。

なお例では jQueryも削除したが、jQueryをロードすること自体に問題はないため必要ならば残しておいても構わない。AngularJSにとって都合が良くないのは DOMを直接操作することであって jQueryではない。AngularJS用の追加モジュールにも jQueryを必要とするものがある(AngularJS自体にも jQuery相当の機能が内蔵されているそうだが、それでは足りない場合もあるのだろう)。

おまけの datepicker

同じカテゴリの記事

Angular.JSでselect要素にoptionをぶら下げる色々な方法 2014年3月29日
AngularJSで、時間のかかる通信の間にモーダルを使ってプログレスバーを表示する 2014年3月18日
HTML5アプリケーションでの、サーバとクライアントの時差について 2014年3月17日
AngularJSの $resourceを使って application/x-www-form-urlencoded 形式のリクエストを POSTする 2014年3月15日
AngularJSと UI Bootstrapで日付と時刻の入力をする 2014年3月14日

お勧めカテゴリ

英語でアニメ観ようず
なじみ深い日本製アニメの英語版DVDで、字幕と音声から英語を学びましょうという趣旨のシリーズ記事です。
ScalaのようでJavaだけど少しScalaなJSON API
Scalaと Spring Frameworkを使って REST的なJSON APIを実装してみましょう。
ドクジリアン柔術少女 すから☆ぱいそん
代表 嶋田大貴のブログです。写真は神仏に見せ金をはたらく罰当たりの図