Posted at

AngularJSでroutingするときには、フォルダ構成をしっかりしておきましょう

More than 5 years have passed since last update.


事の発端

AngularJSのサンプルを参照しながらroutingを行い以下の様な設定にしました。

angular.module('foo', []).

config(function($routeProvider, $locationProvider)
{
$locationProvider.html5Mode(true);
// ルートプロバイダに設定
return $routeProvider.
when('/', {controller:TopCtrl, templateUrl:'top.html'}).
when('/a', {controller:ACtrl, templateUrl:'a.html'}).
when('/b', {controller:BCtrl, templateUrl:'b.html'}).
when('/b/:Id', {controller:BDetailCtrl, templateUrl:'detail.html'}).
otherwise({redirectTo:'/'});
}
);

意図としては、ローカルで動かしたときのURLをhttp://localhost:8080とすると、


  1. http://localhost:8080/」ならtop.htmlの内容表示

  2. http://localhost:8080/a」ならa.htmlの内容表示

  3. http://localhost:8080/b」ならb.htmlの内容表示

  4. http://localhost:8080/b/(なんらかのID)」ならdetail.htmlの内容表示

のつもりでしたが、設定したroutingでは4番目の「http://localhost:8080/b/(なんらかのID)」にブラウザでアクセスしたところ、detail.htmlの内容が表示されない……

ちなみにローカルでnginxを動かしていたため、設定でミスってたかなと思いいろいろいじってみるも改善は見られず、そもそもnginxでこけるならブラウザに表示されてないと判断したのでこの方向性での調査はここで打ち切り。


nginx.conf

server {

listen 8080;
server_name localhost;

location / {
root (プロジェクトがある場所の絶対パス);
index index.html index.htm;
try_files $uri /index.html;
}

location ~ ^/.+/$ {
rewrite .* /index.html last;
}

location ~ /\.ht {
deny all;
}
}



結果どうなったのよ

先ほどの「4番目のroute設定が意図通り表示されない」ところを細かく見ていくと、以下のindex.htmlのng-viewの箇所がdetail.htmlに置き換わらず、index.htmlの内容が再び表示されるというのが発生している現象でした。

例を出すと、


index.html

<body>

<!-- Nav Bar -->
<header class="head">
<!-- ヘッダーの中身 -->
</header>

<!-- ビューが各URLにより変更される -->
<div ng-view></div>

<!-- Footer -->
<footer class="row">
<!-- フッターの中身 -->
</footer>

</body>



index.html

<body>

<!-- Nav Bar -->
<header class="head">
<!-- ヘッダーの中身 -->
</header>

<!-- Nav Bar -->
<header class="head">
<!-- ヘッダーの中身 -->
</header>

<!-- ビューが各URLにより変更される -->
<div ng-view></div>

<!-- Footer -->
<footer class="row">
<!-- フッターの中身 -->
</footer>

<!-- Footer -->
<footer class="row">
<!-- フッターの中身 -->
</footer>

</body>


なふうに展開されてたと。つまりdetail.htmlの内容がそもそもロードされてないことに気づいたので、テンプレートとなるファイルを一箇所にまとめて、route設定を以下のようにしました。

angular.module('foo', []).

config(function($routeProvider, $locationProvider)
{
$locationProvider.html5Mode(true);
// ルートプロバイダに設定
return $routeProvider.
when('/', {controller:TopCtrl, templateUrl:'/template/top.html'}).
when('/a', {controller:ACtrl, templateUrl:'/template/a.html'}).
when('/b', {controller:BCtrl, templateUrl:'/template/b.html'}).
when('/b/:Id', {controller:BDetailCtrl, templateUrl:'/template/detail.html'}).
otherwise({redirectTo:'/'});
}
);

意図通りに表示された!\(^o^)/