AngularJSの基礎


## controllerからの値の受け渡し

controllerから$scopeを使って値を渡す

```js:myscript.js
var mainCtrl = function($scope) {
  $scope.users = [
    {"name":"tagtag", "score":"100"},
    {"name":"namnam", "score":"30"},
    {"name":"lenlen", "score":"40"}
  ];
  $scope.today = new Date();
}
```
Angulerを使っているというng-appの指定を忘れずに！

```html:index.html
<!DOCTYPE html>
<html lang="ja" ng-app>
<head>
  <meta charset="utf-8">
  <title>AngularJSの練習</title>
  <script src="http://code.jquery.com/jquery.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js"></script>
  <script src="myscript.js"></script>
</head>
<body>
  <h1>AngularJSの練習</h1>
  <input type="text" ng-model="name">
  <div ng-controller="mainCtrl">
    <p>{{users.length}} users.</p>
	// パイプオプション指定ができる
    <p>{{25 * 500|number}}</p>
    <p>{{25 * 500|currency:"¥"}}</p>
    <p>{{today|date:'yyyy-MM-dd'}}</p>
    <ul>
	  // ng-repeatで配列を展開
      <li ng-repeat="user in users">
		// 大文字表記と、小数点の表記
        {{user.name|uppercase}}{{user.score|number:4}}
      </li>
    </ul>
  </div>
</body>
</html>
```

```出力結果
3 users.

12,500

¥12,500.00

2014-07-02

TAGTAG100.0000
NAMNAM30.0000
LENLEN40.0000
```

## checkbox・radiobutton

```html:index.html
<p>18+ <input type="checkbox" ng-model="user.adult" ng-true-value="adult" ng-false-value="child"></p>
<p>Phone:
// ng-modelを同様の名前にすれば同グループとして扱ってくれる
<input type="radio" ng-model="user.phone" value="iphone">iphone
<input type="radio" ng-model="user.phone" value="Android">Android
</p>
<p>Memo:
// {{140-user.memo.length}}で文字カウントを表示してくれる
<textarea ng-model="user.memo" ng-maxlength="140"></textarea>{{140-user.memo.length}}
</p>
<p><input type="submit" value="add"></p>
```
### selectboxの値の所得(ng-options)

```html:index.html
<p>Color:
<select ng-model="user.color" ng-options="'label:'+color for color in ['red','blue','pink']" ng-init="user.color='red'"></select>
</p>
```


## 配列を展開する(ng-repeat)

### 降順・昇順・上位でソート
```html:index.html
<ul>
  // orderByで降順、limitToで上位3つ
  <li ng-repeat="user in users|orderBy:'score'|limitTo:3">
    {{user.name}}{{user.score}}
  </li>
</ul>
```
### formの入力値でソート

```html:index.html
// 「query.name」name条件でソート
<p><input type="text" ng-model="query.name"></p>
<ul>
	// 入力値でfilter
	<li ng-repeat="user in users|filter:query">
		{{user.name}}{{user.score}}
	</li>
</ul>
```

### 出力される要素の順番

```html:index.html
// $indexが要素の順番
// $first等は要素の一番上か、真ん中か、下かを表している
<li ng-repeat="user in users|filter:query">
	{{$index+1}} {{$first}} {{$middle}} {{$last}} {{user.name}}{{user.score}}
</li>
```


## controllerを入れ子にする
`ng-controller="userItemCtrl"` を追加

```html:index.html
<div ng-controller="mainCtrl">
    <ul>
      <li ng-repeat="user in users" ng-controller="userItemCtrl">
        {{user.name}}{{user.score}}
        <button ng-click="increment()">+1</button>
      </li>
    </ul>
</div>
```
**親要素の内容を継承するので、そのまま子要素で使える**

```js:myscript.js
var mainCtrl = function($scope) {
  $scope.users = [
    {"name":"tagtag", "score":"100"},
    {"name":"namnam", "score":"30"},
    {"name":"lenlen", "score":"40"},
    {"name":"tagtag", "score":"100"},
    {"name":"namnam", "score":"30"},
    {"name":"lenlen", "score":"40"},
    {"name":"tagtag", "score":"100"},
    {"name":"namnam", "score":"30"},
    {"name":"lenlen", "score":"40"},
    {"name":"tagtag", "score":"100"},
    {"name":"namnam", "score":"30"},
    {"name":"lenlen", "score":"40"}
  ];
  $scope.today = new Date();
}

var userItemCtrl = function($scope) {
  $scope.increment = function() {
    $scope.user.score++;
  }
}
```

## formのvalidation

### 必須項目の入力チェック

```html:index.html
// novalidateでhtml5のvalidatinを無効化する
<form novalidate name="myForm" ng-submit="addUser()">
  <p>Name:<input type="text" name="name" ng-model="user.name" required ng-minlength="4" ng-maxlength="10">
  <span ng-show="myForm.name.$error.required">required</span>
  <span ng-show="myForm.name.$error.minlength">too short</span>
  <span ng-show="myForm.name.$error.maxlength">too long</span>
  </p>
  <p><input type="submit" value="add"></p>
</form>
```
### email・urlの入力チェック

```html:index.html
<p>Score:
<input type="number" name="score" ng-model="user.score">
</p>
<p>Email:
<input type="email" name="email" ng-model="user.email">
<span ng-show="myForm.email.$error.email">not email</span>
</p>
<p>Url:
<input type="url" name="url" ng-model="user.url">
<span ng-show="myForm.url.$error.url">not url</span>
</p>
```

## TODOリストを作ってみよう

```html:index.html
<div ng-controller="mainCtrl">
  <p>Finished task: {{getDoneCount()}} / {{tasks.length}}
  <button ng-click="deleteDone()">Deleate task</button>
  </p>
  <ul>
    <li ng-repeat="task in tasks">
	  // checkboxのng-modelは指定するとbooleanになる(?)
      <input type="checkbox" ng-model="task.done">
      <span class="done-{{task.done}}">{{task.body}}</span>
      <a href ng-click="tasks.splice($index,1)">[x]</a>
    </li>
  </ul>
  <form ng-submit="addNew()">
    <input type="text" ng-model="newTaskBody">
    <input type="submit" value="add">
  </form>
</div>
```

```js:Anguler.js
var mainCtrl = function($scope, $http) {
  $scope.tasks = [
    {"body":"do this 1", "done":false},
    {"body":"do this 2", "done":false},
    {"body":"do this 3", "done":true},
    {"body":"do this 4", "done":false},
  ];
  $scope.addNew = function() {
	// pushメソッドで配列に追加する
    $scope.tasks.push({"body":$scope.newTaskBody,"done":false});
    $scope.newTaskBody = '';
  }
  $scope.getDoneCount = function() {
    var count = 0;
    angular.forEach($scope.tasks, function(task) {
      count += task.done ? 1 : 0;
    });
    return count;
  }
  $scope.deleteDone = function() {
    var oldTasks = $scope.tasks;
    $scope.tasks = [];
    angular.forEach(oldTasks, function(task) {
      if (!task.done) $scope.tasks.push(task);
    });
  }
}

```