先日 AngularJS のルーティング機能を試したけど、サンプルではモデルをコントローラーごとに作成していた。でも、プロダクトコードだとコントローラーやモデルは再利用しやすいように、AngularJS のモジュールにするはず。特にモデルは。
そういうわけで、モデルとコントローラーをモジュール化してみる。
まず、モデルの定義は factory メソッドを使う。
angular.module("services", ["ngResource"]). factory("Guest", function($resource) { // API の URL を指定してモデルを作成 var Guest = $resource("/guests/:id"); return Guest; });
次に、コントローラーの定義は controller メソッドを使う。
angular.module("controllers", ["services"]). controller("MainCtrl", function($scope, Guest) { // query でコレクションを取得 $scope.guests = Guest.query(); }). controller("NewCtrl", function($scope, $location, Guest) { $scope.guestName = ""; $scope.addGuest = function() { Guest.save({ name: $scope.guestName }, function(guest) { // 作成に成功したら一覧に戻る $location.path("/"); }); $scope.guestName = ""; }; });
最後にルーティング。コントローラーの名前を文字列で指定しないと、上手く動いてくれない。
angular.module("app", ["controllers"]). config(["$routeProvider", function($routeProvider) { $routeProvider. when("/", { templateUrl: "/index.html", controller: "MainCtrl" }). when("/new", { templateUrl: "/new.html", controller: "NewCtrl" }); }]);
Web API と HTML テンプレートを含んだコード全体は次の通り。
# coding: utf-8 require "sinatra" require "json" # データはメモリ上に保存 GUESTS = [] get "/" do erb :home end # ゲスト一覧を JSON で取得する API get "/guests" do content_type :json, :charset => "utf-8" GUESTS.to_json end # ゲストを追加する API post "/guests" do # POST したデータを params から取得できなかったので # body を JSON にパース @guest = JSON.parse(request.body.read.to_s) GUESTS << @guest content_type :json, :charset => "utf-8" @guest.to_json end # 一覧ページ用のテンプレートを返す get "/new.html" do erb :new end # 作成ページ用のテンプレートを返す get "/index.html" do erb :index end __END__ @@ home <!DOCTPE html> <html ng-app="app"> <head> <meta charset="utf-8"> <title>Angular Sample</title> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js"></script> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular-resource.min.js"></script> <script type="text/javascript"> angular.module("services", ["ngResource"]). factory("Guest", function($resource) { // API の URL を指定してモデルを作成 var Guest = $resource("/guests/:id"); return Guest; }); </script> <script type="text/javascript"> angular.module("controllers", ["services"]). controller("MainCtrl", function($scope, Guest) { // query でコレクションを取得 $scope.guests = Guest.query(); }). controller("NewCtrl", function($scope, $location, Guest) { $scope.guestName = ""; $scope.addGuest = function() { Guest.save({ name: $scope.guestName }, function(guest) { // 作成に成功したら一覧に戻る $location.path("/"); }); $scope.guestName = ""; }; }); </script> <script type="text/javascript"> angular.module("app", ["controllers"]). config(["$routeProvider", function($routeProvider) { $routeProvider. when("/", { templateUrl: "/index.html", controller: "MainCtrl" }). when("/new", { templateUrl: "/new.html", controller: "NewCtrl" }); }]); </script> </head> <body> <div ng-view></div> </body> </html> @@ index <a href="#/new">New</a> <ul ng-controller="MainCtrl"> <li ng-repeat="guest in guests">{{ guest.name }}</li> </ul> @@ new <a href="#/">Back</a> <div ng-controller="NewCtrl"> <input type="text" ng-model="guestName" placeholder="Input name"/> <button ng-click="addGuest()">Add</button> </div>