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' とすると someCtrlcontroller: 'SomeCtrl', controllerAs: 'controller' とすると controller が、 コントローラ名を指定しないと $ctrl が、テンプレートの中でコントローラを指し示すようになります。

どうも AngularJS 2 ではスコープの概念がなくなり値はコントローラのプロパティとして保持するように変わるみたいです。今のうちからスコープを使わないように変更しておくべきかもしれません。

directive の他の機能

directive のオプションである requiretransclude はそのまま使えるみたいです。

restrictE 固定で AC は使えません。

これは component というより全体の新機能ですが bindings に指定できる値が & = @ のほかに < が増えているようです。これは = に似ていて値を直接バインディングできます。違いは1方向であることです。外から属性が変更されるとコントーローラの値が変更されますが、コントローラの値を変更しても外の値は変わりません。今まで1方向バインディングは、コードを気をつけて書くくらいしか方法がなかったので便利そうです。