Angular最速マスターへの道 第5章

Blog Single

Angular最速マスターへの道 第5章です!
え、やっと・・・?え、まだ・・・?
マスターへの道はこれからが険しくなりそうですが、今回もやっていきましょう!

第5章目次

  • NgTemplateOutlet
  • class, styleのバインディング

NgTemplateOutlet

htmlを書いていると、同じhtml内のあちこちでtemplateが全く同じものを使い回すことって結構よくあると思います。
使用している値が違うだけでも書かないといけなかったり。
Angularはそういう際に子Componentを量産したりもしますが、Componentを作るほどの量じゃないんだよな。。。ということも当然ありますよね?
そういう時に大活躍するのがNgTemplateOutlet!!
大好きNgTemplateOutlet←

ではまず、簡単なパターンから説明していきます。

<div class="first-block">
    <ng-container *ngTemplateOutlet="textTemp"></ng-container>
</div>

<div class="second-block">
    <ng-container *ngTemplateOutlet="textTemp"></ng-container>
</div>

<ng-template #textTemp>
    こんにちは!今日もいい天気ですね!
</ng-template>

<ng-container>ngTemplateOutletというDirectiveで、どのtemplateをそこに呼び出すかを設定しています。
この場合はtextTempと名付けたtemplateを二箇所で呼び出していますね。
おや、案外簡潔に書けますね。

続いてtemplateの構成自体は同じで、templateに値を渡す場合。

export NgTemplateOutletComponent {
    public item1 = {name: 'item1', price: 1000, stock: 3};
    public item2 = {name: 'item2', price: 2000, stock: 10};
}
<div class="item1-block">
    <ng-container *ngTemplateOutlet="itemTemp; context: {$implicit: item1}"></ng-container>
</div>

<div class="item2-block">
    <ng-container *ngTemplateOutlet="itemTemp; context: {$implicit: item2, class: 'text-red'}"></ng-container>
</div>

<ng-template #itemTemp let-item let-class="class">
    <h2 [class]="class">商品名: {{item.name}}</h2>
    <p>値段: {{item.price}}</p>
    <small>在庫数: {{item.stock}}</small>
</ng-template>

NgTemplateOutletクラスにはngTemplateOutletContextというプロパティがあり、そのプロパティに値を渡すことでtemplate内でその情報を使えるようにできます。
context: オブジェクトの形式で値を渡してやるのですが、少しここでややこしい点が。
$implicitというキーに値を設定し、templateでlet-変数名と定義すると、その変数名で値を使用することができます。
上の例の場合は、$implicitにそれぞれitem1とitem2を渡して、変数itemとしてtemplate内で使用できるようにしています。
また、$implicit以外にも値を渡したい場合は、好きなキー名でcontextを設定して、templateにlet-変数名="設定したキー名"で定義すると使えるようになります。

文章だけで説明すると、ちょっと難しく感じてしまうでしょうか。。。
とりあえずどのような感じで表示されるのかDEMOで見てみましょう!

DEMOはこちら

DEMOのコードはこちら

私自身もNgTemplateOutletを使い始めた頃は「$implicitってなんだ?」って感じでしたので、今難しいと感じた方も焦らなくて大丈夫だと思います。
ngForでindexやfirst・lastなどを使うやり方と少し似てるかなという雰囲気で覚え始めるといいかもしれません。
慣れるとバンバン使いたくなる時が来るはずですよ笑

class, styleのバインディング

classやstyleをつける際にcomponentのプロパティなどの値によって適用するCSSを変えたい場合に、値をバインディングすることができます。
方法はいくつかありますので紹介していきます。

NgClass

ngClassというDerectiveを使用してclassをバインドする方法です。
keyにクラス名、valueにクラスを適用する条件を指定したオブジェクトを渡します。
このvalueがtrueで判定された際にクラスが適用されるということです。
早速どのように書くのか見てみましょう。

@Component({
    selector: 'ng-class',
    templateUrl: './ng-class.component.html',
    styles: [`
        .red {
            color: red;
        }
        .blue {
            color: blue;
        }
    `]
})
export NgClassComponent {
    public clicked: boolean = false;
    public textClass = {'red': false, 'blue': true};
}
<!--/ng-class.component.html-->
<p [ngClass]="{'red': true}">赤色になるよ</p>

<p [ngClass]="textClass">青色になるよ</p>

<button (click)="clicked = true">クリック</button>
<p [ngClass]="{'red': !clicked, 'blue': clicked}">クリックすると青色になるよ</p>

書き方は何パターンかありますが、templateに直接書いたり、プロパティを渡したり、はたまたメソッドを渡すこともできます。
条件が変わると適用されるクラスが自動で変わるので非常に便利です。

NgStyle

ngStyleというDirectiveを使用してstyleをバインドする方法です。
keyにスタイル名、valueにその値を指定したオブジェクトを渡します。
書き方は先ほどのNgClassとほとんど同じですが、少し変わったkeyの形式があるのでそれだけご紹介します。

export NgStyleComponent {
    public fontSize: number = 8;
}
<p [ngStyle]="{'font-size.px': fontSize}">8pxの文字ですよ</p>
<p [ngStyle]="{'font-size': '8px'}">8pxの文字ですよ</p>

上の2つは表示上は全く同じです。
今回のfont-sizeのように、pxなどの単位が必要になるCSSの場合、keyをこのように書くこともできます。
個人的には、単位をあらかじめ書いたkeyの方が使いやすくていいと思いますね。

NgStyleを使わないStyleのバインディング

今度はNgStyleを使わない方法です。
早速どのようになるか見てみましょう。

export TempStyleBindComponent {
    public widthRate: number = 50;
}
<div [style.width.%]="widthRate" [style.text-align]="center">幅が50%のdivですよ</div>

先ほどのNgStyleと違い、1スタイルごとに[style.スタイル名]の形を書いていきます。
NgStyleとこの書き方、どちらでも間違いではありません。
使う方の好みやコードルールに応じて選択するので問題ないとおもいます。
ただ複数のスタイルを適用したいのであればNgStyleの方がオブジェクトで一気に指定できるため楽だとは思います!

CSS Binding DEMO

どうCSSが変わっていくか実際に触った方がわかりやすいと思うので、
ご紹介したバインディングを詰め込んだDEMOも見てみてください。

DEMOはこちら

DEMOのコードはこちら

まとめ

ちょっとNgTemplateOutletだけはすぐに慣れるのが難しいかもしれません。
ですが今回ご紹介したものは、使えるようになると絶対に便利な機能ばかりですので、Angularマスターへの大きな一歩になる(はず)です!

次章予告

  • Service

参考

Angular最速マスターへの道シリーズはGitHubに公開しています。

Posted by Mao Miyaji
千葉にある夢の国を愛して止まない、元「魚のお姉さん」のエンジニア。PHP, TypeScriptメインで、暇さえあれば色々な言語を一かじり。

Other Posts: