Angular ディレクティブ

備忘録

#1.ngif(真偽で表示切替)
## 構文1
~~~
<element * ngif="condition">
 ...contents...
</element>
=====================
element: 任意の要素
condition]: 条件式
contents: 引数 conditionがtrueの時に表示されるコンテンツ
=====================
~~~
## 構文2
~~~
<element * ngif="condition"; then trueTemplate; else elseTemplate>
</element>

<ng-template #trueTemplate>
 ...contents...
</ng-template>

<ng-template #elseTemplate>
 ...contents...
</ng-template>

=====================
element: 任意の要素
condition: 条件式
contents: 引数
trueTemplate: 条件式がtrueの場合に表示されるテンプレート 名称任意
elseTemplate: 条件式がfalseの場合に表示されるテンプレート 名称任意 
=====================
~~~


## 記述例
~~~typescript
import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
  <form>
    <label for="ageinput">年齢</label>
    <input #ageinput for="ageinput" name="ageinput" type="text">
  </form>

  <input type="button" (click)="check(ageinput.value)" value="年齢チェック">

  <!--*ngif 条件がtrueの場合"trueContent"を出力 falseの場合"elseContent"を出力-->
  <div *ngIf="firstdisplay; then trueContent; else elseContent">
  </div>  
      
  <ng-template #trueContent>
    <p>判定前です</p>
  </ng-template>
      
  <ng-template #elseContent>
    <p>{{ageEffortText}}</p>
  </ng-template>
  `,
})
export class AppComponent  {
  firstdisplay = true; // 初期表示判定
  age10chk: boolean; // 年齢が10歳超えているかどうか判定
  ageEffortText = ""; // 判定結果表示用

  check(ageinput :number){
    this.firstdisplay = false;
    console.log(ageinput);
    if (ageinput < 10){
      this.age10chk = true;
      this.ageEffortText = "年齢が10歳未満です";
    }else{
      this.age10chk = false;
      this.ageEffortText = "年齢が10歳以上です";
    }
  }
}


~~~
## 表示
- 初期表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404257/a193e762-cca1-f9eb-4a5d-92d0975a1f1d.png)

- 1入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404257/61ebc697-2d03-f902-21f8-80e18a44f10c.png)

- 11入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404257/6290fc12-398c-919b-3400-6ca1f0e37e37.png)


# 2.ngswitch(式の値で表示切替)
## 構文
~~~
<parent [ngswitch]="exp">
  <child *ngSwitchCase="value1">...</child>
  <child *ngSwitchCase="value2">...</child>
  <child *ngSwitchDefault>...</child>
</parent>
=====================
parent, child: 任意の要素
exp: 式
value: 値
=====================
~~~
## 記述例
~~~typescript
import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
  <form>
    <label for="ageinput">年齢</label>
    <input #ageinput for="ageinput" name="ageinput" type="text">
  </form>

  <input type="button" (click)="check(ageinput.value)" value="成人チェック">

  <!--*ngswitch 値によって出力切り替え-->
  <div [ngSwitch]="ageType">
    <p *ngSwitchCase="'age_under20'">20歳未満</p>
    <p *ngSwitchCase="'age_20-59'">20～59歳</p>
    <p *ngSwitchCase="'age_over60'">60歳～</p>
    <p *ngSwitchDefault>未判定もしくは入力不正</p>
  </div>  
  `,
})
export class AppComponent  {
  ageType = "";
  check(ageinput :number){
    console.log(ageinput);
    if(ageinput < 20){
      this.ageType = "age_under20";
    }else if (ageinput < 60) {
      this.ageType = "age_20-59";
    } else {
      this.ageType = "age_over60";
    }
  }
}
~~~
## 表示
- 初期表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404257/2a6e8221-1dd2-89dd-6905-edcb98f30326.png)

- 12入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404257/c6c503f8-93e0-8dd6-b727-28adc7a1ea18.png)

- 33入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404257/293cbd25-cb39-ee6d-87c4-dc7691683352.png)

- 100入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404257/c076a9ff-4811-3972-164d-947d33491213.png)

#3.ngFor(配列をループ処理)
## 構文
~~~
<element *ngFor="let tmp of list">
</element>
=====================
element: 任意の要素
tmp : 仮変数
list: 配列
=====================
~~~
## 記述例
~~~typescript
import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
  <div *ngFor="let member of members">
    <p>{{member.name}} {{member.age}}</p>
  </div>  
  `,
})
export class AppComponent  {
  members = [
    {
      name : "taro",
      age : 11
    },
    {
      name : "shigeru",
      age : 52
    },
    {
      name : "kayoko",
      age : 120
    },
  ]
}
~~~
## 表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404257/a3fa8a6d-1170-2c10-81b0-76f68e84e761.png)


#3.ex1 ngForで使える特殊変数
## 変数
| 変数 | 概要 |
| --- | --- |
| index | ループ回数(o～) |
| first | 最初の要素がどうか |
| end | 最後の要素がどうか |
| even | index値が偶数かどうか |
| odd | index値が奇数かどうか |
## 記述例
~~~typescript
import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
  <table class="table" border="1">
    <tr>
      <th>index</th>
      <th>name</th>
      <th>age</th>
      <th>first</th>
      <th>last</th>
      <th>even</th>
      <th>odd</th>
    </tr>
    <tr *ngFor="let member of members; index as index;first as first;last as last;even as even;odd as odd">
      <td>{{index}}</td>
      <td>{{member.name}}</td>
      <td>{{member.age}}</td>
      <td>{{first}}</td>
      <td>{{last}}</td>
      <td>{{even}}</td>
      <td>{{odd}}</td>
    </tr>
  </table>
  `,
})
export class AppComponent  {
  members = [
    {
      name : "taro",
      age : 11
    },
    {
      name : "shigeru",
      age : 52
    },
    {
      name : "kayoko",
      age : 120
    },
    {
      name : "miho",
      age : 12
    },
  ]
}
~~~

## 表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404257/8c068721-9749-b99b-00cd-f45bee1df92c.png)


#3.ex2 ng-container　異なる要素のセットを繰り返し出力する
## 構文
~~~
<ng-container *ngFor="let tmp of list">
  <content>
  <content>
</ng-container>
~~~
## 記述例
~~~typescript
import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
  <ng-container *ngFor="let member of members;first as first;last as last">
    <div>
      <p>-------------------------</p>
      <p style="font-size: 150%; color: red;">{{member.name}}</p>
      <p>{{member.age}}</p>
      <p *ngIf="member.age > 20">成人です</p>
      <p *ngIf="last">最終行</p>
    </div>
  </ng-container>
  `,
})
export class AppComponent  {
  members = [
    {
      name : "taro",
      age : 11
    },
    {
      name : "shigeru",
      age : 52
    },
    {
      name : "kayoko",
      age : 120
    },
    {
      name : "miho",
      age : 12
    },
  ]
}


~~~
## 表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404257/f41c7271-bfda-d5ba-e229-7c737615600c.png)


#3.ex3 trackBy トラッキング式　配列要素の追加／削除を効率的に追跡する
ngForはオブジェクトの同一性をもとに配列要素の追加／削除を監視しているが、
データが同じでもオブジェクトが異なるとすべて再作成になる
trackByを使用すると差分のみの作成になり、パフォーマンスの改善になる
## 構文
~~~
<element *ngFor="let tmp of list; trackBy: trackFn">
</element>

trackFn(index: any, tmp: any){
    return tmp.id;
}
=====================
tmp : 仮変数
id: 要素(一意に判別できるものである必要あり)
=====================
~~~
## 記述例
~~~TypeScript
import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
  <ng-container *ngFor="let member of members; trackBy: trackFn">
    <p>{{member.name}}({{member.age}})</p>
  </ng-container>
  <input type="button" (click)="onclick()" value="更新" />
  `,
})
export class AppComponent  {
  members = [
    {
      memberId : 1,
      name : "taro",
      age : 11
    },
    {
      memberId : 2,
      name : "shigeru",
      age : 52
    },
    {
      imemberIdd : 3,
      name : "kayoko",
      age : 120
    },
    {
      memberId : 12,
      name : "miho",
      age : 12
    },
  ]
  onclick(){
    this.members = [
      {
        memberId : 1,
        name : "taro",
        age : 11
      },
      {
        memberId : 2,
        name : "shigeru",
        age : 52
      },
      {
        imemberIdd : 3,
        name : "kayoko",
        age : 120
      },
      {
        memberId : 4,
        name : "sakiko",
        age : 12
      },
      {
        memberId : 12,
        name : "miho",
        age : 12
      },
    ]

  }
  trackFn(index: any, member: any){
    return member.memberId;
  }
}

~~~