AngularJS 2 に向けて移行しやすくするために AngularJS 1.5 から directive
のかわりに component
という API が使えるようになっているので試してみます。
インストール
ビルドには Browserify と Babel を使うことにします。
$ npm install -g browserify
$ npm install -D babelify babel-preset-es2015
$ npm install -S angular
Hello, component!
Hello, World から試してみます。
// a.js
import angular from 'angular';
angular.module('app', []).component('greeting', {
template: '<div>Hello, component!</div>'
});
<!DOCTYPE html>
<meta charset="utf-8">
<script src="bundle.js"></script>
<div ng-app="app">
<greeting></greeting>
</div>
$ browserify -t [ babelify --presets es2015 ] -o bundle.js a.js
angular.module(...).component('greeting', ...)
で <greeting>
要素を定義しています。 directive
は第二引数に関数を渡すのに対して component
はオブジェクトを渡しています。少しだけ API がシンプルになってわかりやすくなっています。
これを表示すると Hello, component! と表示されるはずです。
バインディング
AngularJS といえばバインディングなので component
でもやってみます。
// a.js
import angular from 'angular';
angular.module('app', []).component('greeting', {
bindings: {
to: '='
},
controller: class {
constructor() {}
},
template: `<div>Hello, {{ $ctrl.to }}!</div>`
});
<!DOCTYPE html>
<meta charset="utf-8">
<div ng-app="app" ng-init="name = 'World'">
<input ng-model="name">
<greeting to="name"></greeting>
</div>
表示すると入力欄と Hello, World!
というテキストが表示されます。入力欄の値を変更するとテキストも一緒に変更されます。
bindings
というオプションで to
という属性をバインドしています。 directive
だと同じことをするのに scope
を使っていました。違いはバインドされるオブジェクトです。 scope
に指定したものはスコープオブジェクトにバインドされていたのに対して、 bindings
ではコントローラに値が渡されます。テンプレートの中では {{ $ctrl.to }}
として値を取り出しています。
$ctrl
はデフォルトのコントローラ名です。 controller: 'SomeCtrl as someCtrl'
とすると someCtrl
が controller: 'SomeCtrl', controllerAs: 'controller'
とすると controller
が、 コントローラ名を指定しないと $ctrl
が、テンプレートの中でコントローラを指し示すようになります。
どうも AngularJS 2 ではスコープの概念がなくなり値はコントローラのプロパティとして保持するように変わるみたいです。今のうちからスコープを使わないように変更しておくべきかもしれません。
directive の他の機能
directive
のオプションである require
と transclude
はそのまま使えるみたいです。
restrict
は E
固定で AC
は使えません。
これは component
というより全体の新機能ですが bindings
に指定できる値が &
=
@
のほかに <
が増えているようです。これは =
に似ていて値を直接バインディングできます。違いは1方向であることです。外から属性が変更されるとコントーローラの値が変更されますが、コントローラの値を変更しても外の値は変わりません。今まで1方向バインディングは、コードを気をつけて書くくらいしか方法がなかったので便利そうです。