blog

ウェブデザイナーがはじめる AngularJS シリーズウェブデザイナーがはじめるAngularJS:AngularUI Routerの基礎知識

    • Ryuichi Nonaka
    この記事は書かれてから1年以上経過しており、内容が古い場合があります。

    はじめに

    前回のウェブデザイナーがはじめるAngularJS:ngRouteを使ったシンプルなViewの切り替えでngRouteを使いました。今回はより高機能なAngularUI Routerを使ってみます。今回はngRouteでやったことと同じことをAngularUI Routerでやってみたいと思います。

    AugularUI Routerとは

    AngularUI Routerとは、ngRouteと同じルーティングモジュールのひとつ。ngRouteはURLを元にルーティングしていましたが、AngularUI Routerは状態(State)を元にルーティングを行います。State/Viewの入れ子ができ、複数のViewを作れるのが特徴です。

    AngularUI Routerインストール

    $ bower install angular-ui-router --save-dev
    bower angular-ui-router#*   not-cached git://github.com/angular-ui/ui-router.git#*
    bower angular-ui-router#*      resolve git://github.com/angular-ui/ui-router.git#*
    bower angular-ui-router#*     download https://github.com/angular-ui/ui-router/archive/0.2.13.tar.gz
    bower angular-ui-router#*      extract archive.tar.gz
    bower angular-ui-router#*     resolved git://github.com/angular-ui/ui-router.git#0.2.13
    bower angular-ui-router#~0.2.13          install angular-ui-router#0.2.13
    
    angular-ui-router#0.2.13 vendor/bower_components/angular-ui-router
    └── angular#1.3.15
    

    SprocketsにPathを通す

    ########################
    #
    # Sprockets setting
    #
    ########################
    after_configuration do
      sprockets.append_path '../vendor/bower_components'
      sprockets.append_path '../vendor/bower_components/angular'
      sprockets.append_path '../vendor/bower_components/angular-route'
      sprockets.append_path '../vendor/bower_components/angular-ui-router/release'
    end
    

    ngRouteをAngularUI Routerに置き換える

    前回の記事で作成したサンプルをAngularUI Routerに置き換えてみます。同じことをするだけであればほとんど作りは変わりません。

    テンプレート

    Viewとなるテンプレートに変更はありません。AngularUI Routerに対応させるためにindex.html.erbscript.jsに手を加えます。

    index.html.erb

    まずリンクを指定しているng-hrefディレクティブがui-srefに代わり、valueが状態の名前home, loginになります。合わせてng-viewディレクティブをui-viewに変更します。

    <nav class="c-nav">
      <ul class="nav-list">
        <li class="list-item"><a ui-sref="home">Home</a></li>
        <li class="list-item"><a ui-sref="login">Login</a></li>
      </ul>
    </nav>
    
    <section class="c-section">
      <div ui-view>
        ...
      </div>
    </section>
    

    script.js

    ModuleとRouterの定義のみ下記のように変更します。

    // Moduleの定義
    var example = angular.module('example', ['ui.router']); // 依存Moduleをui.routerに変更
    
    // Routerの定義
    example
      .config(['$stateProvider', '$urlRouterProvider', 
              function( stateProvider, urlRouterProvider ){
                urlRouterProvider.otherwise('/'); // .otherwise({ redirectTo: '/'});
                stateProvider
                  .state('home', { // 状態の名前を定義する
                    url: "/", // URL
                    templateUrl: 'views/home.html' // テンプレート
                  })
                  .state('login', {
                    url: "/login",
                    templateUrl: 'views/login.html',
                    controller: 'LoginCtrl' // コントローラ
                  });
              }
            ]);
    

    これでngRouteと同じことが実現できます。

    AngularUI Routerでできること

    AngularUI Routerはシンプルなルーティングはもちろん、細かなカスタマイズができます。

    Template

    テンプレートはテンプレートファイルだけではなく、シンプルにStringを定義することもできます。

    // in app-states.js (or whatever you want to name it)
    $stateProvider.state('contacts', {
      template: '<h1>My Contacts</h1>'
    })
    

    Lean More: Templates

    Controller

    コントローラはモジュールを指定せずに、直接スコープを定義して使うこともできます。 (テンプレートが定義されていない場合コントローラがインスタンス化されません)

    $stateProvider.state('contacts', {
      template: '<h1>{{title}}</h1>',
      controller: function($scope){
        $scope.title = 'My Contacts';
      }
    })
    

    Lean More: Controllers

    Custom Data to State Objects

    Stateに対してカスタムデータを付与する仕組みがあります。

    // Example shows an object-based state and a string-based state
    
    $stateProvider
      .state('login', {
        templateUrl: 'views/login.html',
        data: {
            customData1: 10,
            customData2: "red"
        } 
      })
    
    function Ctrl($state){
        console.log($state.current.data.customData1) // outputs 10;
        console.log($state.current.data.customData2) // outputs "red";
    }
    

    Lean More: Attach Custom Data to State Objects

    State Change Events / View Load Events

    Stateが変わった時、Viewがロードされた時にイベントを発火させます。

    • $stateChangeStart
    • $stateNotFound
    • $stateChangeSuccess
    • $stateChangeError
    • $viewContentLoading
    • $viewContentLoaded
    $rootScope.$on('$stateChangeStart', 
    function(event, toState, toParams, fromState, fromParams){ ... })
    

    Lean More: State Change Events

    Nested States and Nested Views

    StateやViewを入れ子にすることができます。

    $stateProvider
      .state('login', {})
      .state('login.error', {});
    

    この書き方は一例で色々な書き方があるので、詳しくは下記を読んでみてください。

    Lean More: Nested States and Nested Views

    Multiple Named Views

    複数のViewに対してStateを同時に設定することができます。

    <!-- index.html -->
    <body>
      <div ui-view="header"></div>
      <div ui-view="sidebar"></div>
      <div ui-view="contents"></div>
    </body>
    
    $stateProvider
      .state('home', {
        views: {
          'header': { ... templates and/or controllers ... },
          'sidebar': {},
          'contents': {},
        }
      })
    

    Lean More: Multiple Named Views

    URL Routing

    ルーティングの基本的な部分はngRouteと似ていますが、パラメータの値を正規表現で制限したりクリエパラメータに対応しています。

    Lean More: URL Routing

    終わりに

    かなり細かな制御が可能なRouterであることがよく分かりました。全体像をぱっと確認したい方は以下のガイドがお勧めです。

    次回:ウェブデザイナーがはじめるAngularJS:ngCookiesやngStorageを使ったCookieやlocalStorageへのアクセス

    シリーズ

    1. AngularJSをはじめる前に - AngularJSに関するサイトやスライドまとめ
    2. ウェブデザイナーがはじめるAngularJS:AngularJSをはじめる
    3. ウェブデザイナーがはじめるAngularJS:SPA(Single Page Application)をはじめる前に
    4. ウェブデザイナーがはじめるAngularJS:MiddlemanとBowerで作るAngularJSアプリ開発環境
    5. ウェブデザイナーがはじめるAngularJS:ngRouteを使ったシンプルなViewの切り替え
    6. ウェブデザイナーがはじめるAngularJS:AngularUI Routerの基礎知識
    7. ウェブデザイナーがはじめるAngularJS:ngCookiesやngStorageを使ったCookieやlocalStorageへのアクセス
    8. ウェブデザイナーがはじめるAngularJS:DOM操作系ディレクティブを試す
    9. ウェブデザイナーがはじめるAngularJS:イベント系ディレクティブを試す
    10. ウェブデザイナーがはじめるAngularJS:Promise(Deferred)をつかった非同期処理
    11. ウェブデザイナーがはじめるAngularJS:$httpProviderのInterceptorsを使ってリクエスト・レスポンスを操作する
    12. ウェブデザイナーがはじめるAngularJS:Middlemanでng-annotateを使ったMinify対策
    13. ウェブデザイナーがはじめるAngularJS:コントローラ間の連携
    14. ウェブデザイナーがはじめるAngularJS:AngularJS向けのディレクティブが用意されたUI Bootstrap

    コメント・フィードバック