SiNBLOG

140文字に入らないことを、極稀に書くBlog

AngularJSで連動して動くコンボボックスを作る Part 0

最近、AngularJSをちょこちょこと触り始めました。
しかし、元々jsをあまり知らないので、あんまり自信が無い・・・。


ということで、書いてみた内容をBlogに書くことで、ふるぼっこにされようメソッドを展開することに!

今回作ってみたのは、2つのコンボボックスが連動する画面です。

実際に動いているのは、以下
AngularJS sample


データが1つしか無いので分かりにくいですが、上のコンボボックスを選択すると、下のコンボボックスが変わるって感じです
本当にちょっと動くようにしてみただけって感じなので、ソースもちょっとしかないです。

index.html

<!DOCTYPE html>
<html lang="ja" ng-app>
  <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" ng-init="init()">
  	  <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="/js/main.js"></script>
  </body>
</html>

main.js

function MainController($scope, $http) {
	$scope.init = function() {
		$scope.categories = [{"id" : "1", "name" : "野菜"}];
	};

	$scope.changeCategory = function() {
		$http({
			method: 'GET', 
			url: '/item/list',
			param: $scope.categoryid
		}).
  		success(function(data, status, headers, config) {
  			$scope.items = data;
  		}).
		error(function(data, status, headers, config) {
			console.log('error');
		});
	};

	$scope.submit = function() {
		$http({
			method: 'POST', 
			url: '/store/entry',
			param: $scope.entryForm
		}).
  		success(function(data, status, headers, config) {
  			console.log('success');
  		}).
		error(function(data, status, headers, config) {
			console.log('error');
		});
	};
}

AngularJSの使っている項目は以下の通り

  • ng-controller
  • ng-init
  • ng-model
  • ng-options
  • ng-change
  • ng-submit


それぞれ何に使っているかと、迷っているところを書いていこう

ng-controller
ng-controllerを使わないとAngularJSが始まらない気がするので、formをごそっと囲っている
ただ、気になるのはng-controllerで囲う範囲だ
今はよく分からず、とても大きな範囲で囲っている
それこそ、ページを全部1つのcontrollerで囲う勢いだ
でも、controllerはネストしたりできるようなので、本当はもっと小さく囲うのが正しいのかもしれない
今回だと、コンボボックスが$httpでデータを取ってきたりしているので、select付近に小さなcontrollerとか作ったりするのかもしれない
その場合、controller間のデータのやり取りの仕方がよく分からなかったので、今は大きく囲っちゃっている


ng-init
ng-initは初期処理を呼び出すのに使っている。
これもあんまり良くわかってないけど、今はページ単位で1度だけng-initを使っている
もしかしたら、ng-initがあるDOMが読み込まれた時に1度だけ動くとかなら、必要な箇所で都度書いても良いのかも


ng-model
ng-modelはformの中身を管理するのに使っている
この画面だとformをpostするしかやることがないので、formの中身を持っている
controllerを複数使う場合は、それぞれng-modelがあるのだろうから、また違ってくるのかもしれない


ng-options
ng-optionはoptionタグを動的に出力するのに使っている
Referenceにはいくつかのパターンが記述されていたが、group byってのが何なのかよく分かっていない


ng-change
ng-changeはコンボボックスが変更された時のイベントハンドラとして登録している
これは、こんな感じの使い方で良いんじゃないかと思っている


ng-submit
ng-submitはformがsumitされた時のイベントハンドラとして使っている
$httpのparamにng-modelを渡しているが、これはこんな感じで良いのかな・・・?


と色々と疑問は尽きない
日本語の情報もまだまだ少ないし、これからも試してみた内容をBlogにちょこちょこ書いていきたい

もっといい方法があるよ!って場合は、コメントでもtwitterでもG+でも何でも良いので
教えてもらえると、とっても嬉しい!


上記のソースはgithubに置いている
何故かServer側を適当にgae/gで作ってしまったので、そこはスルーするか、gae/gの方にもツッコミを貰えると嬉しいw
https://github.com/sinmetal/angularjs-sample


2013-05-18追記
色々とアドバイスを貰ったので、更新しました!
AngularJSで連動して動くコンボボックスを作る Part 1 - SinDiary