AngularJSの$routeProviderでControllerとURLをマッピングする
ControllerだけでなくtemplateUrlもマップする
AngularJSの$routeProviderでURLとController、そしてtemplateUrlを対応付けることができる。
AngularJSからRestfulなリクエストを送信のエントリーでは、CakePHPをバックエンドとしてRestfulなAPIを効率的に実装する方法とそのAPIをAngularJSからGETリクエストを送信して取得したデータを表示する方法を書いてみた。
本エントリーでは、バックエンド側のCRUD操作が受け付け可能な状態を想定して、AngularJS側のapp.jsの設定について書いてみる。AngularJSのindex.htmlは、CakePHPのwebroot直下に配置し以下のようにした。
<!doctype html> <html ng-app="myApp"> <head> <title>AngularJS requests CakePHP restful API</title> <link href="app/foundation/css/foundation.min.css" rel="stylesheet" media="screen"> <link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet"> </head> <body ng-controller="AppCtrl"> <div class="row"> <div class="large-12 columns"> <h1>AngularJS requests CakePHP restful API</h1> <ng-view></ng-view> </div> </div> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.10/angular-route.min.js"></script> <script type="text/javascript" src="app.js"></script> <script type="text/javascript" src="controllers.js"></script> </body> </html>
上のコードの中でポイントとなるのが、
<ng-view></ng-view>
の部分になる。このHTMLの中にtemplateUrlで指定した部分HTMLが埋め込まれるイメージとなる。また、
angular-route.min.js
を読み込んでおかないとルーティング設定ができないので読み込んでおく。デザイン的にはFoundationとFont awesomeを設定できるようにしてある。
templateUrlの指定はapp.js内で行う。
$routeProvider
app.js内の$routeProviderでURLとcontrollerのマッピングを行う。具体的には以下のようにした。
(function() { var ajs = angular.module('myApp', [ 'ngRoute', // $routeProvider設定で必須のモジュール 'myApp.controllers' ]); ajs.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) { //$locationProvider.html5Mode(true); $routeProvider .when('/posts', { templateUrl: 'app/partials/posts.html', controller: 'GetRequestCtrl' }) .when('/new', { templateUrl: 'app/partials/new.html', controller: 'NewPostCtrl' }) .otherwise({ redirectTo: '/' }); } ]); }());
上のコードで設定したルーティングは、
- /posts
- /new
の2つを指定してある。それらのURLに対して、
- templateUrl
- controller
をマッピングしている。
templateUrl
templateUrlで指定した部分HTMLは、CakePHPのwebroot配下の以下のパスにした。
webroot\app\partials
そして、posts.htmlを以下のように構成した。
<div ng-controller="GetRequestCtrl"> <h2 class="page-header">Recipe List</h2> <table class="table"> <thead> <tr> <th width="25px">ID</th> <th>TITLE</th> <th>CONTENT</th> <th>CREATED DATE</th> <th width="50px"></th> </tr> </thead> <tbody> <tr ng-repeat="e in recipes"> <td>{{e.Recipe.id}}</td> <td>{{e.Recipe.title}}</td> <td>{{e.Recipe.body}}</td> <td>{{e.Recipe.created|date:'short'}}</td> <td> <a ng-click="editPost($index)"><i class="fa fa-pencil"></i></a> <a ng-click="delPost($index)"><i class="fa fa-eraser"></i></a> </td> </tr> </tbody> </table> <p> <button type="button" class="btn btn-success" ng-click="addPost()"> <b class="fa fa-plus-square"></b>Add Recipe </button> </p> </div>
画像のような表示となる。
posts.htmlのポイントとしてはAngularJSのcontrollerを指定している部分となる。
<div ng-controller="GetRequestCtrl">
GetRequestCtrlでは、バックエンド側のRestful APIにGETリクエストを送信するコードが書いてある。
ページの下部には投稿を追加するためのボタンリンクがあり、そのHTMLは以下のとおり
<button type="button" class="btn btn-success" ng-click="addPost()"> <b class="fa fa-plus-square"></b>Add Recipe </button>
ng-click=”addPost()
の部分でクリックのタイミングでGetRequestCtrlのaddPostを実行するようにイベントを設定している。最終的にGetRequestCtrlは以下のようになった。
ajs.controller('GetRequestCtrl', function($scope, $rootScope, $http, $location) { var load = function() { console.log('loading...'); $http.get($rootScope.appUrl + '/recipes.json') .success(function(data, status, headers, config) { $scope.recipes = data.recipes; }); } load(); // ng-click="addPost() $scope.addPost = function() { $location.path("/new"); // 非同期で/newへ遷移 } });
$routeProviderの使い方をマスターすればAngularJSのテンプレートとコントローラの関係もイメージしやすくなる。