AngularJSのhtml5modeを使いたいけど

AngularJSで書いてみようと思って情報収集すると、大抵$routeProviderでルーティング設定してng-viewでviewを差し替えるサンプルが多く出てくる

 

そんなサンプルを動かしてみるとURLが

http://127.0.0.1:9000/#/test

みたいに"#"がついている

これはフラグメントなので、同一ページでページ遷移してるようにするトリックで、この方法には色々と問題が含まれているらしいけど、その話は置いといて。

 

っで、フラグメントを利用せずに実現するのがHTML5のHistory APIを使った実装らしい。AngularJSでやる場合には

angular.module('testApp', )
  .config(['$locationProvider', function ($locationProvider) {
    $locationProvider.html5Mode(true);
  }
]);

みたいな感じでhtml5modeを有効にしてあげれば

http://127.0.0.1:9000/test

って感じでめでたく"#"が消えましたyo

めでたしめでたし

 

じゃないよね!?

 

 最近はmacで開発が増えているからHTML5に対応したモダンブラウザしか触らないけど、今なお根強い人気??のIE8とかじゃHistory APIには対応していないじゃん!!

なんて心配はちゃんと配慮してあるらしく、HistoryAPIに対応していないブラウザでは

http://127.0.0.1:9000/#/test

に置き換わってHistory APIを利用しないレガシーな動きになるらしい

古くさいWindowsなんてもってないから確認してないけど

これにて一件落着、めでたしめでたし

 

これで終わっちゃダメじゃね!?

 

html5modeを有効にするとルーティング機能が良さげにHistory APIの有効/無効で処理を変えてくれるので、URL体系が"#"無しと有りが共有する事になる。

っで困るのがaタグとかでリンク先を指定するときのパスの書き方

<a href="/test">

って書くとHistory APIが無効の場合に

http://127.0.0.1:9000/test

に飛んでしまう。本当は

http://127.0.0.1:9000/#/test

に飛んで欲しい。

じゃー

<a href="#/test">

って書きたくなるけど、そうするとHitory APIが有効の場合に問題が起きる:(

 

っで、やっと本題。この問題を回避するためには

angular.module('testApp', )
  .controller('PageCtrl', ['$scope', '$location', function ($scope, $location) {
    $scope.linkto = function (path) {
      $location.path(path);
    };
  }
]);

な感じでcontrollerを用意してあげて$locationにpathを設定してあげる。

使い方は

<div ng-controller="PageCtrl">
  <a ng-click="linkto('/test01')">
</div>

って感じで両方のURL体系に対応出来ましたとさ