AngularJSで一覧画面を作る
今日はAngularJSで一覧ページを作ってみました
動いているのは、以下のページ
AngularJS sample
ちょっと、データが適当過ぎて、なんのこっちゃ分からん感がすごいですが、DBから取得したデータを表示しています
登録しているデータは以下のエントリーで作ったFormで登録したデータ
AngularJSで連動して動くコンボボックスを作る Part 1 - SinDiary
まずはソース一覧を列挙して、ちょっとずつ解説をしていきます
index.html
<!DOCTYPE html> <html lang="ja" ng-app="sample"> <head> <meta charset="utf-8"> <title>AngularJS sample</title> <meta name="description" content=""> <meta name="author" content=""> <!-- Le HTML5 shim, for IE6-8 support of HTML elements --> <!--[if lt IE 9]> <script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script> <![endif]--><!-- Le styles --> <link rel="stylesheet" href="/lib/bootstrap/css/bootstrap.min.css"> <link rel="stylesheet" href="/lib/bootstrap/css/bootstrap-responsive.min.css"> <style type="text/css"> body { padding-top: 30px; padding-left: 30px; } </style> </head> <body> <div> <h2>Hello AngularJS !!</h2> <div ng-view></div> </div> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script src="//code.angularjs.org/1.0.6/angular.min.js"></script> <script src="//code.angularjs.org/1.0.6/angular-resource.min.js"></script> <script src="/js/main.js"></script> </body> </html>
main.js
(function() { var app = angular.module('sample', ['ngResource']). config(function($routeProvider) { $routeProvider. when('/', {controller:'ListController', templateUrl:'list.html'}). when('/entry', {controller:'EntryController', templateUrl:'entry.html'}); }); app.controller('ListController', ['$scope', '$resource', function($scope, $resource) { var Store = $resource("/store"); $scope.stores = Store.query(function() { console.log("success store query"); }, function(){ console.log("error store query"); }); }]); app.controller('EntryController', ['$scope', '$location', '$resource', function($scope, $location, $resource) { $scope.categories = [{"id" : "1", "name" : "野菜"}]; var List = $resource("/item/list"); var Store = $resource("/store"); $scope.changeCategory = function() { $scope.items = List.query({id : $scope.entryForm.categoryid}, function(){ console.log("success list"); }, function(){ console.log("error list"); }); } $scope.submit = function($event) { console.log($scope.entryForm); Store.save($scope.entryForm, function(){ console.log("success entry"); $location.path('/'); }, function(){ console.log("error entry"); }); }; }]); })();
list.html
<div> <table class="table"> <thead> <tr> <td>No</td> <td>CategoryId</td> <td>ItemId</td> <td>Name</td> </tr> </thead> <tbody ng-repeat="s in stores"> <tr> <td>{{$index}}</td> <td>{{s.CategoryId}}</td> <td>{{s.ItemId}}</td> <td>{{s.Name}}</td> </tr> </tbody> </table> <a href="#/entry" class="btn btn-primary">Entry</a> </div>
entry.html
<div> <form ng-submit="submit()"> <select ng-model="entryForm.categoryId" ng-options="c.id as c.name for c in categories" ng-change="changeCategory()"> <option value="">-- chose category --</option> </select> <br /> <select ng-model="entryForm.itemId" ng-options="i.id as i.name for i in items"> <option value="">-- chose item --</option> </select> <br /> <input type="text" ng-model="entryForm.name"></input> <br /> <button type="submit" class="btn btn-primary">Save</button> <a href="#/" class="btn">Cancel</a> </form> </div>
これだけです
まずはファイルの構成ですが、以下の様な感じ
- index.html - 最初に表示されるhtml
- main.js - ControllerなどAngularJSを使っているJS
- list.html - 一覧部分のDOMを持つtemplate
- entry.html - EntryFormのDOMを持つtemplate
index.htmlには、ほとんど何も記述されておらず、主なDOMはtemplateにあります
これには以下のような理由があります
index.htmlにAngularJS用のDOMを書くと、AngularJS適用前にチラ見えする
今回だと、list.htmlにあるtableなんかが、index.htmlに書くと、最初にちらちら見えます
特に{{s.CategoryId}}とかが見えるので、ユーザにはなんじゃこりゃ?感が溢れ出ることでしょう
ということで、index.htmlには以下のように書いておきます
<div ng-view></div>
これで、templateの内容をこの中に表示してくれます
特にmoduleとかの名前も付いてないですが、1つのng-appの中で1つしか作れないのかな・・・?
後、重要なところはmain.jsの以下の部分でしょう
var app = angular.module('sample', ['ngResource']). config(function($routeProvider) { $routeProvider. when('/', {controller:'ListController', templateUrl:'list.html'}). when('/entry', {controller:'EntryController', templateUrl:'entry.html'}); });
この部分でpathとController, templateを紐付けています
前のエントリーでcontrollerの範囲が分からないと言いましたが、上記だとそれっぽい範囲になっています
共通で使うmenuみたいなのがあると、また悩み始めると思いますが、少なくともページごとのcontrollerにはなってます
その他のソースは、だいたい前回のエントリーの内容と同じです
AngularJSで連動して動くコンボボックスを作る Part 1 - SinDiary
$routeProvider使う関係で細かい部分は変わっていますが
ソースはgithubにあるので、全体を見たい方は以下をご覧ください
Server側がgae/goではありますが・・・
GitHub - sinmetal/angularjs-sample
今は新規登録しかないですが、編集とか削除もぼちぼち作って行きたいと思います
後、もうちょっと中身のデータをまともなものにしたりとかw
疑問に思っていること
$routeProvider使った状態で、controllerをcontroller関数で生成する方法が分からない・・・
minify対策のこともあるし、直したいところ
AngularJSのDIの仕組み、minify対策は覚えておこう! - Qiita
2013-05-25 修正
コメントでminify対策用のcontrollerの書き方を教えてもらったので、修正しました!
ありがとうございます!