directive の作り方 @ 福岡 angularjs 勉強会(第2回目)
DESCRIPTION
AngularJS の directive の作り方について簡単に紹介しました。TRANSCRIPT
directiveの作り方岩本 海童 (@odiak_)
自己紹介
- 岩本 海童 @ 株式会社カラクル
- 今年の4月 → Rails+AngularJSで店舗・社内向けのSNSを開発中
- AngularJSを始めて半年くらい
- Twitter: odiak_
AngularJSの初心者にありがちなこと
- 「AngularJS便利だけど、DOMの操作ってどうすればいいんだろう?」
- 「directiveってのがあるみたいだけど、なんか難しそう」
directive、難しくないよ!
directiveとは- ロジックとHTMLをつなぐもの
- →scopeのデータをもとにDOMを操作する
- AngularJSでは、DOMをいじるのはdirectiveの仕事
- それ以外の部分はロジックに集中
Service Controller Directive HTMLscopeと
その変化を 監視する仕組み
ロジック UI
組み込みdirective- AngularJSになくてはならない存在
- HTMLの属性の形で使われるもの:ng-click, ng-repeat, ng-controller …
- HTMLの要素の形で使われるもの:a, select, script …
- 組み込みdirectiveも、公開されたAPIのみで作られている
directiveの3つのかたち
- 要素: <my-directive></my-directive>
- 属性: <input my-directive="2">
- クラス: <p class="my-directive"></p>
- directiveによって、どの形で使用可能かが違う。複数指定も可
directiveの処理が開始するまで
- AngularJSがHTMLを上から順に解析する
- → 登録されたdirective名に一致する要素・属性・クラス名があれば処理を開始
- 処理には、compileとlinkがあるcompile→scope作る→link(詳細は省略)
directiveを定義する
var app = angular.module("app", []); app.directive("myDir", function(){ return { // ここにdirectiveの定義 }; });
- directive名は必ずキャメルケースで。 - HTML中の"my-directive"はmyDirectiveとして解釈される
例1) 文字を赤くするdirective
app.directive("red", function(){ return { restrict: "A", link: function(scope, elem, attrs){ elem.css("color", "red"); } }; });
- restrict: directiveのタイプを指定。A:属性、E:要素、C:クラス、デフォルトは"EA"
- link: メインの処理を書く。scope、要素、属性の3つが引数に与えられる。第2引数はjQuery(互換)オブジェクト
使用例
<p>Hello <span red>Directive!</span></p>
例2) テンプレートを使ったdirective
app.directive("user", function(){ return { restrict: "E", scope: { userInfo: "=" }, replace: true, template: '\ <div class="user">\ <img ng-src="{{userInfo.icon}}">\ <p>{{userInfo.name}}</p>\ </div>' }; });
- scope: {userInfo: "="}隔離されたscope中のuserInfo変数に、user-info属性に書かれた式を評価した値を代入
- replace: true後述するテンプレートでその要素を置き換える
- template: "…"HTMLのテンプレート。templateUrl:で、別ファイルのHTMLを使用することもできる。replace: true を指定しない場合、要素内に挿入
使用例
app.controller("TestCtrl", function($scope){ $scope.myUser = { icon: "http://file.odiak.net/images/20140906_angular2.png", name: "岩本 海童" }; });
<div ng-controller="TestCtrl"> <user user-info="myUser"></user> </div>
さらに複雑なデータ形式にしたり、CSSでスタイルを整えれば、似たようなHTMLを何度も書く
ことなく、部品を簡単に再利用できる!!
今まで作ったdirective1. input要素のフォーカスを制御する
2. 画像の配列を指定して、そのリストを生成する(画像の追加・削除も)
3. 画像を正方形に切り取って表示する
4. shiftキーが押されていない状態で enterキーが押された場合に処理を実行する
5. more…
1. input 要素のフォーカスを制御する"isFocused" directive
app.directive('isFocused', function(){ return { restrict: 'A', scope: { isFocused: '=' }, link: function(scope, elem, attrs){ scope.$watch('isFocused', function(value){ if (value) { elem.focus(); } }); elem.on('blur', function(){ scope.$apply(function(){ scope.isFocused = false; }); }); } }; });
- scope.$watch()変数や式を監視して、その値が変化した時にコールバックを呼び出す。
- scope.$apply()引数に与えた関数を実行する。その後、scope内の$watchで登録された式・変数をチェックして、変化があれば$watchのコールバックを呼び出す。
- $watchと$applyの2つがAngularJSのデータバインディングの基本
使用例
<div ng-controller="TestCtrl"> <button ng-click="focusOnInput()">click me </button> <input type="input" is-focused="focused"> </div> (HTMLは一部省略)
angular.module('testApp', []) .controller('TestCtrl', function($scope){ $scope.focusOnInput = function(){ $scope.focused = true; }; });
this.demo();
参考になる資料
Mastering Web Application Development with AngularJS
docs.angularjs.org
angularjsninja.com
console.log("ご静聴ありがとうございました。");