LoginSignup
10
10

More than 5 years have passed since last update.

routeProviderを利用している時に特定のリンクをルーティングから除外する方法

Last updated at Posted at 2014-08-11

AngularJSでrouteProviderで遊んでる時に、ファイルのダウンロードやら画像の直リンクやら
意図しないリンクまでルーティングに含まれてしまう問題の対処方法。

これで3時間位詰まった。。。おそらくBackboneJSでも通用する。しませんでした。


問題

下記のようなルーティングを設定した時、
ng-app内の同一ドメイン内のすべてのリンクに対してルーティング処理が行われ、
PJAXに似た動作をするようになる。

router.js
angular.module("app", ["ngRoute"])
.config([
  "$routeProvider",
  "$locationProvider",
  function($routeProvider, $locationProvider) {
    $locationProvider.html5Mode(true);

    return $routeProvider.when("/", {
      templateUrl: "/template/index.html"
    })
    .when("/page01", {
      templateUrl: "/template/page01.html"
    })
    .when("/page02", {
      templateUrl: "/template/page02.html"
    })
    .otherwise({
      redirectTo: "/"
    });

  }
]);

上記の指定では / /page01 /page02 へのアクセスを行った際に
所定の場所からテンプレートを取得し、ng-viewへ反映する。

ルーティングに該当しなかった場合は /へのリクエストとしてリダイレクトして処理する。

ここで問題となるのが、公開したアプリに下記のようなファイルをダウンロードさせるためのリンクや
画像を直リンクで表示したいといったような意図で設置したリンク。

<a href="/download/hoge.zip">ダウンロードはこちら!</a>

残念ながらこの状態でリンクを設定すると、
AngularJSはリクエストをルーティングに組み込んで処理する。

実際どのように動作するかというと、
/download/hoge.zip をクエリとしてルーティングのマッチングを行う。
当然 router.js の内容に該当するルートはないので、/と同じ内容が表示されてしまう。

かと言ってroute.jsのotherwiseを外したところで内容の取得ができなくなるだけなので
リンクをクリックするとng-viewは空になる。

どうすりゃええのん(´・ω・`)

解決方法

このような場合には下記のように、ルーティングをしてほしくないURLに対して
targetを付加することで解決することができる。

例えばファイルのダウンロードのリンクは下記のようになる。

<a href="/download/hoge.zip" target="_self">ダウンロードはこちら!</a>

また応用として、ルーティングに定義済みのURLでもtargetを付加すると
AngularJSのルーティング処理を意図して解除することができる。

<!-- こっちはルーティングされる -->
<a href="/page01">PAGE01へ</a>

<!-- こっちはルーティングされずにページの更新がかかる -->
<a href="/page02" target="_self">PAGE02へ</a>

今回は同一ページ内で処理したかったのでtarget="_self"を指定したが
もちろん新規ウィンドウで表示したいときはtarget="_blank"などを使うこともできる。

参考

10
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
10