albatrosary's blog

UI/UXとエンタープライズシステム

Angular2 Component or Directive ?

Angular2も含めAngular1.5からコンポーネント指向的な話があり、文字通り@Componentを利用する機会が増えるだろうと思います(Angular2を利用する場合、当然ですが)。ただインジェクションするときに「Componentをdirectivesに書いて」とか「ここはComponentで作るけど、ここはDirectiveにしよう」という話もあり「Component?Directive?ほげ?」みたいな話もあるのでまとめてみる

f:id:albatrosary:20160415114646p:plain

Directives オーバービュー

Angular2のディレクティブには3種類ある:

  1. Components
  2. Structural directives
  3. Attribute directives

「Component(コンポーネント)」はテンプレートと実際のディレクティブから成る。3種類のディレクティブの中でも最も一般的なもので殆どの場合、このComponentを使ってアプリケーションを書くことになる。

「Structural directive(構造ディレクティブ)」は、DOM要素を追加および削除することでDOMの構造を変更させる。 NgForとNgIfの場合は2つともよく知られた例です。

「Attribute directive(属性ディレクティブ)」は、要素の外観や動作を変更させる。たとえば、ビルトインNgStyleディレクティブは、同時に複数の要素のスタイルを変更することができる。

Components

Angular2を始めるとまずはコンポーネントを作ると思うし、資料も多い。

Multiple Components - ts

Component Styles - ts

Component Interaction - ts

Components · Learn Angular 2

(例)

import {Component} from 'angular2/angular2'

@Component({
  selector: 'my-component',
  template: '<div>Hello my name is {{name}}. <button (click)="sayMyName()">Say my name</button></div>'
})
export class MyComponent {
  constructor() {
    this.name = 'Max'
  }
  sayMyName() {
    console.log('My name is', this.name)
  }
}

Structural directives

単一ページアプリケーションの決定的な特徴の一つは、DOMツリーの操作にあります。ユーザナビゲーションにより新しいページが表示される度にDOMのセッション全体が表示されたり消えたりします。下記ドキュメントではAngularを使ってDOMの操作を行う方法を見ることが出来ます。

Structural Directives - ts

(例)

<div *ngIf="hero">{{hero}}</div>
<div *ngFor="#hero of heroes">{{hero}}</div>
<div [ngSwitch]="status">
  <template [ngSwitchWhen]="'in-mission'">In Mission</template>
  <template [ngSwitchWhen]="'ready'">Ready</template>
  <template ngSwitchDefault>Unknown</template>
</div>

Attribute directives

属性ディレクティブは、DOM要素の外観や動作を変更します。

Attribute Directives - ts

(例)

import {Directive, ElementRef, Input} from 'angular2/core';
@Directive({
    selector: '[myHighlight]'
})
export class HighlightDirective {
    constructor(el: ElementRef) {
       el.nativeElement.style.backgroundColor = 'yellow';
    }
}

最後に

Angular2 Cheatsheetを見ると継承関係が書かれていて次のように定義されています。

f:id:albatrosary:20160415133558p:plain:w200

(Directive)

@Directive({ property1: value1, ... })

Directive configuration

  • selector: '.cool-button:not(a)'
  • providers: [MyService, provide(...)]

(Component)

@Component extends @Directive, so the @Directive

Component configuration

  • viewProviders: [MyService, provide(...)]
  • template: 'Hello {{name}}' or templateUrl: 'my-component.html'
  • styles: ['.primary {color: red}'] or styleUrls: ['my-component.css']
  • directives: [MyDirective, MyComponent]
  • pipes: [MyPipe, OtherPipe]

作っていると「providers」と「viewProviders」とどっちを使うべきかみたいなところが出てくると思いますが、こういうことのようです。「providers」は、このディレクティブとその子のための依存性を注入するためで、「viewProviders」は、このコンポーネントビューの範囲で依存性を注入する。