ES5で書くAngular v2（５）「スタイルの適用」

※現在この方法は推奨されません

[前回](http://qiita.com/puku0x/items/9f4b9457a91d36294bf8)作成したToDoサンプルにスタイルを適用してみましょう。

# ngClass

ngClassはAngularJS(v1.x系)でもあった「条件に応じてCSSクラスを切り替える」機能です。

```html:components/todo-component/todo-component.template.html
<style>
.completed {
    text-decoration: line-through;
}
</style>
<div *ngFor="let todo of todoList">
    <label>
        <input type="checkbox" [(ngModel)]="todo.complete" />
        <span [ngClass]="{'completed': todo.complete}">{{todo.title}}</span>
    </label>
</div>
```

上記の例では、チェック状態に連動して取り消し線を表示するといった処理を行っています。
![GIF.gif](https://qiita-image-store.s3.amazonaws.com/0/106886/2aa2cef3-d676-6e35-fca0-209c8c38a1ae.gif)

`[ngClass]="{'クラス1':条件1, 'クラス2':条件2, ...}"` のように複数追加することもできます。

# CSSのカプセル化

Angular v2で作成したコンポーネントのスタイルはShadow DOMをエミュレートしています。
Shadow DOMとは、DOMをカプセル化する機能です。

これにより、スタイルも外部から隠蔽できるため、Webアプリ作成時にありがちな「クラス名の重複により意図しない場所でスタイルが上書きされる」といった問題が解消されます。

では、早速使ってみましょう。

```html:index.html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/2.0.0-beta.17/Rx.umd.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/2.0.0-beta.17/angular2-polyfills.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/2.0.0-beta.17/angular2-all.umd.dev.js"></script>
        <script src="components/todo-component/todo-component.js"></script>
        <style>
            .label {
                color: blue;
            }
        </style>
    </head>
    <body>
        <h1 class="label">Todo list</h1>
        <todo-component></todo-component>
    </body>
</html>
```

↑メインのHTMLには`label`クラスが定義されており、文字色は<font color=blue>青</font>に設定されています。

次は`todo-component`を準備します。

コンポーネント毎にHTML+CSS+JSを揃えておくと良いでしょう。
![image](https://qiita-image-store.s3.amazonaws.com/0/106886/3c3e9d64-eaa3-cf2f-f7c4-e9fc1bc4d317.png)

JavaScriptは以下の通りです。
`templateUrl`の他に`styleUrls`でCSSを指定している部分が追加されています。

```js:components/todo-component/todo-component.js
(function(app) {
    app.TodoComponent = ng.core
    .Component({
        selector: 'todo-component'
    })
    .View({
        templateUrl: 'components/todo-component/todo-component.template.html',
        styleUrls: ['components/todo-component/todo-component.css'],
    })
    .Class({
        constructor: function() {
            this.todoList = [{'title': 'ToDo_01', 'complete': false},
                             {'title': 'ToDo_02', 'complete': false},
                             {'title': 'ToDo_03', 'complete': false},
                       ];

        },
        add: function(title) {
            var todo = {'title': title, 'complete': false};
            this.todoList.push(todo);
        }
    });
    document.addEventListener('DOMContentLoaded', function() {
        ng.platform.browser.bootstrap(app.TodoComponent);
    });
})(window.app || (window.app = {}));
```

CSSファイル内では以下のように、`label`クラスを定義しています。
Shadow DOMの効果を示すため、ここでは**index.htmlで定義したものと同じクラス名** で文字色を<font color=red>赤</font>に変更しています。

```css:components/todo-component/todo-component.template.css
.label {
    color: red;
}
```

最後にHTMLテンプレートを上記のCSSクラスを利用するように変更します。

```html:components/todo-component/todo-component.template.html
<div>
    <input type="text" [(ngModel)]="todo"/>
    <button (click)="add(todo)">Add</button>
</div>
<li *ngFor="let todo of todoList">
    <span class="label">{{todo.title}}</span>
</li>
```

このサンプルを実行するとこのように表示されると思います。
![image](https://qiita-image-store.s3.amazonaws.com/0/106886/28672ca7-3ea6-fc31-3855-b043305b4003.png)

Shadow DOMにより、見出しとコンポーネントそれぞれに同名のクラスを適用できるようになりました。

動くサンプルはCodepenで見ることが出来ます。
http://codepen.io/puku0x/pen/PNvyQa

# まとめ
今回は

- ngClass
- CSSカプセル化 (Shadow DOM)

を紹介しました。

スタイルに関しては、`styles`や`styleUrls`で指定する方法以外にも、テンプレートHTMLに`<style>`を直書きする方法があります。ちょっと試してみたい時には使えそうですね。

[次回](http://qiita.com/puku0x/items/11531d7b1a6fa20d4a83)はフォームバリデーションをやってみます。