AngularJSで連動して動くコンボボックスを作る Part 1
以下のエントリーで作成したサンプルをGoogle+のAngularJS JPコミュニティにサンドバッグとして投下した結果
AngularJSで連動して動くコンボボックスを作る Part 0 - SinDiary
親切にふるぼっこにした上、pull requestまで送ってくれました!
G+
https://plus.google.com/u/0/114061805681880927213/posts/JpmZpC5CsNW
pull request
サンドバック part1 by teyosh · Pull Request #2 · sinmetal/angularjs-sample · GitHub
指摘してくださった内容は、以下の通り。
- ng-appにmoduleを設定しましょう
- controllerはcontroller関数で設定しましょう
- categoriesの初期化にng-initはいらないかな
- itemsとentryにはngResourceを使うと便利
- factory使ったりdirectiveで隠蔽したりすればもっといいかも
- form validationの機能もあるので使うといいかも
上記全て対応できたわけではないのですが、ある程度修正したのが以下のソース
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"> </head> <body> <div ng-controller="MainController"> <h2>Hello AngularJS !!</h2> <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">submit</button> </form> </div> <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"]); app.controller("MainController", function($scope, $resource){ $scope.categories = [{"id" : "1", "name" : "野菜"}]; var List = $resource("/item/list"); var Entry = $resource("/store/entry"); $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) { Entry.save($scope.entryForm, function(){ console.log("success entry"); }, function(){ console.log("error entry"); }); }; }); })();
それぞれ、修正した箇所は以下の辺り
ng-appにmoduleを設定しましょう
<html lang="ja" ng-app="sample"> ・・・ <script src="//code.angularjs.org/1.0.6/angular-resource.min.js"></script>
var app = angular.module("sample", ["ngResource"]);
ng-appにmoduleを設定することで、angularの中にControllerなどが作れるようになりました
名前空間も汚染しないし、良い感じです
ngResourceも使うようになったので、jsの読み込みも増えています
controllerはcontroller関数で設定しましょう
app.controller("MainController", function($scope, $resource){
ng-appにmoduleを設定したので、Controllerもangularの中に作ります。
categoriesの初期化にng-initはいらないかな
$scope.categories = [{"id" : "1", "name" : "野菜"}];
load時に最初のコンボボックスの初期化にng-initを使っていたのだけど、普通に一番上に書いておけば良いみたい
itemsとentryにはngResourceを使うと便利
var List = $resource("/item/list"); var Entry = $resource("/store/entry"); ・・・ $scope.items = List.query({id : $scope.entryForm.categoryid}, function(){ ・・・ Entry.save($scope.entryForm, function(){
Server側をREST APIの形にすると、もっと便利らしいのだけど、今はこんな感じに
$httpを使っていた時より、シンプルになって良いです
と今の段階だと、この程度ですが、まだまだ機能があるようで、勉強が必要です
アドバイスしてもらった内容で、まだ分かってないこともあるので、その辺りから攻めなきゃ
色々とアドバイスしてくださった上に、pull requestまで送っていただいたTessei Yoshidaさんありがとうございました!