AngularJSを使ってみて思ったんだが、ng-**というアトリビュートの扱いが独特なのだが、{{**}}という記述は、正規表現を使って文字列置換させているのだろうか?
だとすると、一度ページを読み込んで置換しているんだとすると、少し効率が悪いような気がするんだが、そんなベタな事はやってないだろう。
ライブラリを解析するのは、もう少し後でやるとしよう。
今回は、前回の続きを行う。
前回は、リピートやフィルタ処理の簡単な使い方を書いたので、dotinstallをベースにその続きをお勉強した備忘録とソースコードを記載する。
関連サイト
本家サイト
https://angularjs.org/
dotinstall
http://dotinstall.com/lessons/basic_angularjs
今回の勉強の目次
- コントローラのネストとイベント
- form関連
コントローラのネストとイベント
ソースコード
<!DOCTYPE html>
<html lang="js" ng-app>
<head>
<meta charset="UTF-8">
<title>AngularJS</title>
<!-- <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script> -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.6/angular.js"></script>
<script src="myscript.js"></script>
</head>
<body>
<h1>AngularJS</h1>
<h2>インクリメント処理</h2>
<blockquote>
controllerを使ってボタンを押すと数値が「1」足される<br>
<div ng-controller="mainCtrl">
<ul>
<li ng-repeat="list in listsMore" ng-controller="userItemCtrl">
{{list.site}} / {{list.domain}} / {{list.number}}
<button ng-click="increment()">+1</button>
</li>
</ul>
</div>
</blockquote>
</body>
</html>
var mainCtrl = function($scope){
$scope.listsMore = [
{"site":"Google" , "domain":"google.com" , "number":210} ,
{"site":"Yahoo" , "domain" : "yahoo.com" , "number":20} ,
{"site":"Apple" , "domain" : "apple.com" , "number":230} ,
{"site":"Ideacompo" , "domain":"ideacompo.com" , "number":40} ,
{"site":"Amazon" , "domain" : "amazon.com" , "number":250} ,
{"site":"Twitter" , "domain" : "twitter.com" , "number":60} ,
{"site":"Facebook" , "domain":"facebook.com" , "number":270} ,
{"site":"Line" , "domain" : "mobile.line.me" , "number":80} ,
{"site":"dotinstall" , "domain" : "dotinstall.com" , "number":290} ,
{"site":"github" , "domain":"github.com" , "number":100} ,
{"site":"Redmine" , "domain" : "edmine.jp" , "number":310} ,
{"site":"Linux" , "domain" : "jp.linux.com" , "number":120}
];
};
var userItemCtrl = function($scope){
$scope.increment = function(){
$scope.list.number++;
};
};
解説
myScript.jsには「mainCtrl」と「userItemCtrl」を別のfunctionで記述しているのだが、AngularJSでは、DOM階層で入れ子にすると、extendsされて、ネスト扱いにしてくれるようだ。
要するに、mainCtrlではデータ定義をして、userItemCtrlでは、データ操作をするMVCモデルっぽい構造体を持つことができる。
う〜ん、便利・・・あれ?prototype構造はAngularJSでは考慮されているのか???後ほど考えてみよう・・・
ポイントは以下の3つだが、さほど難しくないので、詳細説明はスル〜する。
・ng-controller
・ng-repeat
・ng-click
form関連
AngularJSはバリデーション関連を強力に指定することができるのが便利。
ソースコード
<!DOCTYPE html>
<html lang="js" ng-app>
<head>
<meta charset="UTF-8">
<title>AngularJS</title>
<!-- <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script> -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.6/angular.js"></script>
<script src="myscript.js"></script>
</head>
<body>
<h1>AngularJS</h1>
<h2>FORM処理</h2>
<blockquote>
<div ng-controller="mainCtrl">
<form novalidate name="myForm" ng-submit="addSite()">
<p>Name :
<input type="text" name="name" ng-model="list.name" required ng-minlength="5" 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>Score :
<input type="number" name="score" ng-model="list.score">
</p>
<p>Email :
<input type="email" name="email" ng-model="list.email">
<span ng-show="myForm.email.$error.email">Not valid Email !</span>
</p>
<p>Web :
<input type="url" name="url" ng-model="list.url">
<span ng-show="myForm.url.$error.url">Not valid URL !</span>
</p>
<p>18+ :
<input type="checkbox" ng-model="list.adult" ng-true-value="adult" ng-false-value="child">
</p>
<p>Phone:
<input type="radio" ng-model="list.phone" value="iPhone">
<input type="radio" ng-model="list.phone" value="Android">
</p>
<p>Memo:
<textarea ng-model="list.memo" ng-maxlength="140"></textarea>{{140 - list.memo.length}}
</p>
<p>Color:
<select ng-model="list.color" ng-options="'label : '+ color for color in ['red' , 'blue' , 'green']" ng-init="list.color='blue'"></select>
</p>
<p><input type="submit" value="add"></p>
</form>
<pre>{{list | json}}</pre>
</div>
</blockquote>
</body>
</html>
var mainCtrl = function($scope){
$scope.addSite = function(){};
};
※submit処理はサーバーサイドプログラムが必要になるため、今回は割愛。
解説
属性
formタグに「novalidate」を追記するのは、HTML5の元々持っているバリデーションを無効化するおまじないと考えよう。
required : 入力必須
ng-minlength : 最低入力文字数
ng-maxlength : 最大入力文字数
※文字数は半角も全角もそれぞれ1文字扱いになるようだ。
バリデーション
バリデーションに引っかかった場合のエラー表示するために「ng-show」を使っているが、値がtrueの場合に表示するという処理で、内部構造を理解しておこう。
必須項目
form名 / 項目名(input) / AngularJSのエラーイベント / 属性(minlengthとmaxlengthにはng-というプレフィックスが付かないので注意)
myForm.name.$error.required
その他の項目種類
Checkbox : true / false 判定により、value値を切り替える事が可能。
Radio : ng-modelを共通にすることでname値と同じ扱いにできる。※これって実際に使う時POSTできないな・・・JSON部分を送信する事になるね。
textarea : {{140 - list.memo.length}}の部分は残り文字数のカウントをしている。
select
なにかと複雑なselectタグもAngularJSではサクッとセットできます。
"ng-options"に配列を与えてあげるだけで項目リストが完成です。
ラベル部分の装飾などはソースを参考にしてもらうといいですが、複雑なリストになる場合は、JS関数と連動させるといいでしょう。
"ng-init"はselected要素ですが、リストに存在しない場合は、自動でblank要素が作られます。
referrence
本家のリファレンスページを参照してより複雑なform処理を簡単にセットしてみましょう。
https://docs.angularjs.org/api/ng/directive/form
0 件のコメント:
コメントを投稿