AngularJSの$locationサービスを使ってURLを操作する方法、使用例をまとめました。
デモとコードサンプルはこちら。
※目次をクリックすると目次の下部にコンテンツが表示されます。
$locationサービスの概要
・$locationサービスは、ブラウザのアドレスバーのURLを解析し、AngularJSアプリでURLを利用できるようにする。
・window.locationをベースにしている。
・アドレスバー内のURLの変更は$locationサービスに反映され、そして$locationサービスを使ってURLを設定するとブラウザのアドレスバーに反映される。
・$locationサービスを使ってURLを変更した際、ページ全体のリロードを行わない。URL変更後のページリロードを行う場合は、$window.location.hrefを使用する。
・window.locationをベースにしている。
・アドレスバー内のURLの変更は$locationサービスに反映され、そして$locationサービスを使ってURLを設定するとブラウザのアドレスバーに反映される。
・$locationサービスを使ってURLを変更した際、ページ全体のリロードを行わない。URL変更後のページリロードを行う場合は、$window.location.hrefを使用する。
$locationサービスの使用方法
1)url、path、search、hashによるURLの指定
下記URLを例に示します。
http://localhost/path1/path2?ke11=val1&key2=val2#top
①path(target)メソッド
・ドメイン名以降、クエリー文字列やハッシュ以外のパス部分(/path1/path2)を指定できる。
・引数を指定しない場合、現在のURLのパスをリターンする。
②search(key, val)メソッド
・URLのクエリ文字列(?ke11=val1&key2=val2)を指定する。
・引数を指定しない場合、現在のURLのクエリ文字列の変数部分をリターンする。
③hash(target)
下記URLを例に示します。
http://localhost/path1/path2?ke11=val1&key2=val2#top
①path(target)メソッド
・ドメイン名以降、クエリー文字列やハッシュ以外のパス部分(/path1/path2)を指定できる。
・引数を指定しない場合、現在のURLのパスをリターンする。
②search(key, val)メソッド
・URLのクエリ文字列(?ke11=val1&key2=val2)を指定する。
・引数を指定しない場合、現在のURLのクエリ文字列の変数部分をリターンする。
③hash(target)
・URLのハッシュ部分(#top)を指定する。
・引数を指定しない場合、URLのハッシュ部分をリターンする。
・hash(target)メソッドを使ってハッシュ部を設定した際に<p id=”top”>のようにid属性で指定したページ内位置にスクロールさせたい場合は、$anchorScrollサービスを使用する。
④url(target)メソッド
・path、search、hashを含めたURL全体(/path1/path2?ke11=val1&key2=val2#top)を設定できる。
・引数を指定しない場合、path、search、hashを含めたURL全体(/path1/path2?ke11=val1&key2=val2#top)をリターンする。
⑤$locationChangeSuccessイベント
URLが変更された後にイベントが通知される。
HashbangモードとHtm5モード
1)HashbangモードとHtm5モードのURLの指定方法
ベースのURLが下記の場合を例として説明します。
http://localhost/sub/sample.html
①hashbangモード
現在アクセスしているHTMLのURL(http://localhost/ng/sample.html)末尾にhashbang(#!)を追加し、その後に$locationサービスで指定したURLを追加する。
例)$location.url(“/path1/path2?ke11=val1&key2=val2#top”)
ブラウザのURL
http://localhost/ng/sample.html#!/path1/path2?ke11=val1&key2=val2#top
②html5モード
baseタグ(例:<base href=”/ng/” />の後ろに$locationサービスで指定したURLを追加する。
例)$location.url(“/path1/path2?ke11=val1&key2=val2#top”)
ブラウザのURL
http://localhost/ng/path1/path2?ke11=val1&key2=val2#top
2)Hashbangモードの指定方法
デフォルトはHashbangモードで、ハッシュ部は”#”の文字が使用される。”!#”を指定する場合は、$locationProviderを使って設定する。
demoApp.config(function ($locationProvider) {
$locationProvider.html5Mode(false).hashPrefix(“!”);
});
3)Html5モードの概要と指定方法
①概要
・HTML5 history APIを介してブラウザのURLアドレスを処理する。
・ブラウザがHTML5 history APIをサポートしていない場合は、自動でHashbangモードを使ってURLを処理するように対応する。
②指定方法
デフォルトはHashbangモードなので下記のように$locationProviderを使って設定する。
demoApp.config(function ($locationProvider) {
$locationProvider.html5Mode(true).hashPrefix(“!”);
});
4)HTML5モード使用時の注意点
オンラインマニュアルにいろいろ記載されていました。まだよく理解できていないのでとりあえず備忘としてメモ書きしています。
●html5モードでのリンクリライト
①非対応ブラウザ
<a href=”/some?foo=bar”>link</a>
対応ブラウザ /some?foo=bar
非対応ブラウザ /index.html#!/some?foo=bar
②リンクリライトが行われず、フルページロードされる場合
・target属性が指定されている場合
<a href=”/ext/link?a=b” target=”_self”>link</a>
・他ドメインの絶対URLが指定されている場合
<a href=”http://angularjs.org/”>link</a>
・’/’で始まる異なるペースパス
<a href=”/not-my-base/link”>link</a>
●相対リンク
・html5Mode.requireBaseをfalseに設定していない場合は、下記のように相対リンクのベースとなるURLを指定する。
<head>
<base href=”/app” />
</head>
この設定によって、CSS、スクリプト、画像などの相対リンクがHTML5モード設定時に正しいURLが解決される。
●サーバー側の設定
サーバー側ですべてのリンクURLをホームURL(index.htmlなど)にリライトする設定が必要。
●クローラにクロールさせる
クローラにAJAXアプリをインデックスさせたい場合は、下記タグを記述する。
<meta name=”fragment” content=”!” />
この記述をするとクローラは”_escaped_fragment_”のパラメータをつけてサーバーにリクエストを送り、サーバーはこのパラメータを認識して、HTMLスナップショットをリターンする。
ベースのURLが下記の場合を例として説明します。
http://localhost/sub/sample.html
①hashbangモード
現在アクセスしているHTMLのURL(http://localhost/ng/sample.html)末尾にhashbang(#!)を追加し、その後に$locationサービスで指定したURLを追加する。
例)$location.url(“/path1/path2?ke11=val1&key2=val2#top”)
ブラウザのURL
http://localhost/ng/sample.html#!/path1/path2?ke11=val1&key2=val2#top
②html5モード
baseタグ(例:<base href=”/ng/” />の後ろに$locationサービスで指定したURLを追加する。
例)$location.url(“/path1/path2?ke11=val1&key2=val2#top”)
ブラウザのURL
http://localhost/ng/path1/path2?ke11=val1&key2=val2#top
2)Hashbangモードの指定方法
デフォルトはHashbangモードで、ハッシュ部は”#”の文字が使用される。”!#”を指定する場合は、$locationProviderを使って設定する。
demoApp.config(function ($locationProvider) {
$locationProvider.html5Mode(false).hashPrefix(“!”);
});
3)Html5モードの概要と指定方法
①概要
・HTML5 history APIを介してブラウザのURLアドレスを処理する。
・ブラウザがHTML5 history APIをサポートしていない場合は、自動でHashbangモードを使ってURLを処理するように対応する。
②指定方法
デフォルトはHashbangモードなので下記のように$locationProviderを使って設定する。
demoApp.config(function ($locationProvider) {
$locationProvider.html5Mode(true).hashPrefix(“!”);
});
4)HTML5モード使用時の注意点
オンラインマニュアルにいろいろ記載されていました。まだよく理解できていないのでとりあえず備忘としてメモ書きしています。
●html5モードでのリンクリライト
①非対応ブラウザ
<a href=”/some?foo=bar”>link</a>
対応ブラウザ /some?foo=bar
非対応ブラウザ /index.html#!/some?foo=bar
②リンクリライトが行われず、フルページロードされる場合
・target属性が指定されている場合
<a href=”/ext/link?a=b” target=”_self”>link</a>
・他ドメインの絶対URLが指定されている場合
<a href=”http://angularjs.org/”>link</a>
・’/’で始まる異なるペースパス
<a href=”/not-my-base/link”>link</a>
●相対リンク
・html5Mode.requireBaseをfalseに設定していない場合は、下記のように相対リンクのベースとなるURLを指定する。
<head>
<base href=”/app” />
</head>
この設定によって、CSS、スクリプト、画像などの相対リンクがHTML5モード設定時に正しいURLが解決される。
●サーバー側の設定
サーバー側ですべてのリンクURLをホームURL(index.htmlなど)にリライトする設定が必要。
●クローラにクロールさせる
クローラにAJAXアプリをインデックスさせたい場合は、下記タグを記述する。
<meta name=”fragment” content=”!” />
この記述をするとクローラは”_escaped_fragment_”のパラメータをつけてサーバーにリクエストを送り、サーバーはこのパラメータを認識して、HTMLスナップショットをリターンする。
サンプルコード
1)path、search、hash、urlメソッドを使ってURLを指定(デフォルトとHashbangモード使用)
2)$anchorScrollを使ってページ内スクロール
下記のように各記事のid属性を使って各記事部分にhash(id)メソッドを使ってスクロールできるようにします。
<span id=”27″ ng-class=”{‘bg-primary’: item.focus}”>記事 27</span>
hash(id)メソッドを使って指定したid属性部分にスクロールさせたい場合は、下記のように$anchorScrollをコントローラの引数に指定します。
demoApp.controller(“location2Ctrl”, function ($scope, $location, $anchorScroll)
このサンプルでは、指定した記事にスクロールした際に分かりやすくするためにng-classディレクティブを使って記事の背景色を設定しています。
2)$anchorScrollを使ってページ内スクロール
下記のように各記事のid属性を使って各記事部分にhash(id)メソッドを使ってスクロールできるようにします。
<span id=”27″ ng-class=”{‘bg-primary’: item.focus}”>記事 27</span>
hash(id)メソッドを使って指定したid属性部分にスクロールさせたい場合は、下記のように$anchorScrollをコントローラの引数に指定します。
demoApp.controller(“location2Ctrl”, function ($scope, $location, $anchorScroll)
このサンプルでは、指定した記事にスクロールした際に分かりやすくするためにng-classディレクティブを使って記事の背景色を設定しています。
デモとコードサンプルはこちら。