Deep Insider の Tutor コーナー
>>  Deep Insider は本サイトからスピンオフした姉妹サイトです。よろしく! 
AngularJS TIPS

AngularJS TIPS

URL経由でパラメーター情報を引き渡すには?($routeProviderプロバイダー)

2016年4月4日

ngRouteモジュールを使ったAngularJSのルーティングで、URL経由でパラメーター情報を引き渡す方法を解説する。

  • このエントリーをはてなブックマークに追加

 別稿「TIPS:ルーティング機能を実装するには?」では、ngRouteモジュールを利用したルーティング機能の実装について解説しました。本稿では、引き続きルーティング機能を利用して、URL経由でパラメーター情報を引き渡す方法を解説します。

 この機能を利用することで、例えば「~/contents/10」のようなURLにアクセスすると、ルートパラメーターidに対して10という値がセットされるようになります。ルートパラメーターには、コントローラーなどからアクセスできますので、一般的には、その情報をキーとして、サーバーサイドから具体的なコンテンツを取得することになるでしょう。

 では、以下に具体的なコードを見ていきます。基本となるサンプルは、前掲の別稿で解説したものを利用しますので、全体のコードはそちらを併せて参照してください。

ルーティング情報の定義

 ルートパラメーターを受け取れるようにするには、まず、$routeProviderプロバイダーのwhenメソッドで、URLパターンを修正します。

JavaScript
angular.module('myApp', [ 'ngRoute' ])
  .config(['$routeProvider', function($routeProvider){
    $routeProvider
      .when('/', {
        templateUrl: 'views/home.html',
        controller: 'HomeController'
      })
      .when('/contents/:id', {
        templateUrl: 'views/contents.html',
        controller: 'ContentsController'
      })
      ……中略……
      });
  }]);
「/contents/~」でルートパラメーターを受け取るためのコード(route.js)

 :名前の形式で表されているのは、ルートパラメーターのプレイスホルダーです。マッチしたURLに応じて、対応する値がルートパラメーターにセットされます。従って、「~/contents/10」であればid10になりますし、「~/contents/hoge」であればidhogeとなります。

 ここでは、ルートパラメーターを1つだけ定義していますが、例えば「/contents/:category/:id」のようにすることで、複数のパラメーター(この場合はcategoryid)を埋め込むこともできます。

ルートパラメーターを受け取る方法

 ルートパラメーターを受け取るには、$routeParamsサービスを利用します。以下のように、コントローラーに依存性注入した上で、$routeParams.名前の形式でアクセスします。

JavaScript
angular.module('myApp')
  ……中略……
  .controller('ContentsController', ['$scope', '$routeParams', function($scope, $routeParams) {
    $scope.id = $routeParams.id;
  }])
ルートパラメーターを参照するコントローラーの例(controller.js)
HTML
<div>
  <h1>個別記事</h1>
  <p>連載 第{{id}}回</p>
</div>
ルートパラメーターを表示するテンプレートの例(contents.html)
HTML
……前略……
<ul>
  <li><a ng-href="#/home">ホーム</a></li>
  <li><a ng-href="#/contents/10">記事を読む</a></li>
  <li><a ng-href="#/tags/angular/javascript/jquery">関連記事を検索</a></li>
</ul>
……後略……
ルートパラメーターを指定したリンクの例(main.html)
「~/contents/10」でアクセスした結果

さまざまなルートパラメーター

 プレイスホルダーに「?」「*」などの記号を付与することで、省略可能なパラメーター可変長パラメーターを表現することもできます。

1省略可能なパラメーター

 先ほどの例では、「~/contents/10」「~/contents/hoge」のようなURLにはマッチしますが、「~/contents/」にはマッチしません。デフォルトでは、ルートパラメーターidが必須であるからです。

 もしも「~/contents/」――:idパラメーターの省略を許容したい場合には、ルートパラメーターの後方に?を付与します。例えば以下のようにです。

JavaScript
.when('/contents/:id?', {
  templateUrl: 'views/contents.html',
  controller: 'ContentsController'
})
ルートパラメーターidを省略可能にするコード(route.js)

 また、ルートパラメーターを省略可能にした場合、一般的にはコントローラー側で省略時の挙動を明確にしておくべきでしょう。例えばここでは、スコープ変数idに「」を設定します。

JavaScript
.controller('ContentsController', ['$scope', '$routeParams', function($scope, $routeParams) {
  $scope.id = $routeParams.id ? $routeParams.id : '-';
}])
ルートパラメーター省略時にデフォルト値を設定するコード(controller.js)

 この状態で、「~/contents/」にアクセスすると、確かに以下のような結果が得られるはずです。

「~/contents/」でアクセスした結果
2可変長パラメーター

 「:list*」のように、名前の後方に*を付与することで、「/」をまたいで、以降のパスを1つの変数にまとめることもできます。

 例えば以下のようなURLパターンを設定した場合、URL「~/tags/angular/javascript/jquery」に対するルートパラメータlistの値は「angular/javascript/jquery」となります。

JavaScript
.when('/tags/:list*', {
  templateUrl: 'views/tags.html',
  controller: 'TagsController'
})
可変長パラメーターを定義するコード(route.js)
JavaScript
.controller('TagsController', ['$scope', function($scope) {
  $scope.list = $routeParams.list;
}]);
可変長パラメーターを設定するコード(controller.js)
HTML
<div>
  <h1>タグ{{list}}による検索</h1>
  <p>...検索結果...</p>
</div>
可変長パラメーターを表示するテンプレートの例(tags.html)
「~/tags/angular/javascript/jquery」でアクセスした結果

 $routeParamsの戻り値は(配列などではなく)「/」区切りの文字列である点に注意してください。実際に利用する際には、手元で分割などする必要があるでしょう。

ルートの優先順位

 複雑なパターンを指定するようになると、ルートを追加する順序にも気を付ける必要があります。ルートは追加された順に判定され、複数のルートにマッチする場合には最初にマッチしたものが優先されるからです。

 例えば以下のような順序で定義されたルートは、正しく動作しません。

  1. /:group/:id
  2. /contents/:id

 この場合、例えば「~/contents/13」のようなリクエストがあっても、1のルートにまずマッチしますので(group=contentsid=13、です)、2のルートにマッチすることはありません。

 ルートを追加する際には、必ず「特殊なルートを先に、より汎用的なルートを後に」定義してください。

処理対象:サービス カテゴリ:基本
処理対象:ルーティング(ngRoute) カテゴリ:基本
API:$routeProvider カテゴリ:ngRoute > provider(プロバイダー)
API:$routeParams カテゴリ:ngRoute > service(サービス)

※以下では、本稿の前後を合わせて5回分(第49回~第53回)のみ表示しています。
 連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。

AngularJS TIPS
49. AngularJSを手動で起動するには?(bootstrap)

通常は自動起動するAngularJSを手動で起動するにはangular.bootstrapメソッドを使用する。その基本的な使い方を解説。

AngularJS TIPS
50. ルーティング機能を実装するには?($routeProviderプロバイダー)

AngularJSではngRouteモジュールを利用したルーティングが可能だ。その基本的な用法(ルーティングの定義/コントローラー/テンプレートなど)について解説する。

AngularJS TIPS
51. 【現在、表示中】≫ URL経由でパラメーター情報を引き渡すには?($routeProviderプロバイダー)

ngRouteモジュールを使ったAngularJSのルーティングで、URL経由でパラメーター情報を引き渡す方法を解説する。

AngularJS TIPS
52. ルーティングの挙動/設定をカスタマイズするには?($routeProviderプロバイダー)

「テンプレートを文字列で指定(templateパラメーター)」「リダイレクト時の規則をカスタマイズ(redirectToパラメーター)」「html5モードに切り替える」という、特によく使われる3つのカスタマイズ方法を取り上げる。

AngularJS TIPS
53. 配列/オブジェクトをコピーするには?(copy)

配列のコピーで、JavaScript標準のconcatメソッドを使う場合とAngularJSのcopyメソッドを使う場合の違いを説明。シャローコピーとディープコピーとは?

サイトからのお知らせ

Twitterでつぶやこう!