AngularでHello,world／テキスト補間

# はじめに
この記事では Text interpolation (テキスト補間) について扱います。
テキスト補間とは、コンポーネントファイルで宣言した変数を、テンプレートファイルで表示するための機能です。
まず基本となる書き方を説明した後、数値や日付に対する書式の設定、それから式と関数を使ったテキスト補間を解説します。
なお、開発環境については、環境準備編を参照してください。  

[AngularでHello,world／環境準備](https://qiita.com/shuji-k/items/4c05655c37d08a10a041)

# 1. 基本
まず、サンプルファイルコードです。

```typescript:app.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  public message = 'hello, world';
}

```

```html:app.component.html
{{message}}
```

上記コードを表示すると、画面に「hello, world!」が表示されると思います。
このように、コンポーネントファイルでpublic宣言された変数名を、```{{}}``` で囲むとテンプレートファイル内でその内容を表示することができます。
注意点として、変数はpublic宣言していることです。private宣言された変数は表示することはできません。
試しに、messege変数をprivate宣言してみましょう。以下のようなメッセージが、プロンプトに表示されます。

```batchfile:プロンプト
Error: src/app/app.component.html:1:3 - error TS2341: Property 'message' is private and only accessible within class 'AppComponent'.
```

エラーメッセージから、テンプレートファイル内テキスト補間のスコープは、コンポーネントファイルの外側ということが分かりますね。  

# 2. 書式設定
書式は、Pipe (パイプ) と呼ばれる仕組みで実現することができます。
まずサンプルとして、数値の書式例を4つ示します。

```typescript:app.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  public message = 12456.789;
}

```

```html:app.component.html
<pre>
  {{message | number: '1.0-0'}}
  {{message | number: '1.1-1'}}
  {{message | number: '1.1-4'}}
  {{message | number: '6.4-4'}}
</pre>
```

書き方として、`|` (バーティカルバー) の後 number と記述し、`:` (コロン) に続いて書式をシングルクォーテーションでくくります。
書式は (整数の最小桁数).(小数点以下最小桁数)-(小数点以下最大桁数) です。
また、地域別の表現にも対応していますが、ここで説明は省略します。詳細は公式リファレンスを参照してください。

[Angular DecimalPipe のリファレンス](https://angular.io/api/common/DecimalPipe)

他にも、日付のパイプラインなどあります。
公式リファレンスでPipeという項目にまとめられているので、必要に応じて確認してください。

[Angular API List のパイプ一覧](https://angular.io/api?type=pipe)

# 3. 式
テキスト補間では、ある程度の JavaScript 式を表現することができます。
例えば、数値計算や文字列の結合ができます。

```typescript:app.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  public message = 2;
}

```

```html:app.component.html
{{'メッセージ: ' + (message + 1)}}
```

`メッセージ: 3` という文字列が表示されましたね。

# 4. 関数
ある程度の JavaScript 式が実行できると説明しましたが、これには関数の呼び出しも含まれます。

```typescript:app.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  public getMessage() { return 'hello, world!'; };
}

```

```html:app.component.html
{{getMessage()}}
```

しかし、関数を呼び出すのはあまりおすすめできません。
Angular は様々なイベントが発生したタイミングで、画面に表示しているテキスト補間に変化が無いか確認しています。
なので、処理の重い関数を表示に使った場合、更新のない関数だとしても実行されてしまうため、アプリケーションの動作が遅くなる原因になります。
サンプルとして、下記のようなコードを作成しました。

```typescript:app.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  private count = 0;
  constructor() {
    this.loop();
  }
  
  public loop() {
    setTimeout(() => {
      this.loop()
    }, 1000);
  }
  
  public getMessage() {
    console.log(this.count);
    this.count ++;
    return 'hello, world!';
  }
}
```

```html:app.component.html
{{getMessage()}}
```

ブラウザの開発者ツールからコンソールを確認しましょう。
1秒ごとに2回カウントアップされているのが分かると思います。2回の呼び出しの振り分けは下記の通りです。

- 1度目の呼び出し: `setTimeout()` タイムアウトイベントにより、`getMessage()` の値が変わっていないか確認のための呼び出し
- 2度目の呼び出し: 1度目の呼び出しによって、`getMessage()` の値が変わっていないか確認のための呼び出し

なぜ2度呼び出しを行うのかについては、Angularの詳しい説明が必要なため、省略いたします。
開発者モードでの実行では、2度の呼び出しが行われると覚えてください。
なお、本番モード※1では、1度しか呼び出されません。
ただこれは、「1度しか呼び出されないから大丈夫！」という意味ではありません。
先ほどお伝えしたように、関数を呼び出す前に値が確定しているのであれば、変数を表示したほうが表示処理コストが低くなります。

※1 正確には、開発者モードを切って実行した場合です。それを分かりやすく本番モードと呼んでいます。  
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869191/4060242a-8056-f115-3bce-cb6b9b23a73a.png)

# 5. サニタイズ
動的にHTMLを変更できるということは、セキュリティの懸念としてサニタイズがあります。
例えば、悪意のある外部スクリプトをテキスト補間で自サイトに埋め込んでしまうとかですね。
しかし、テキスト補間において渡される文字列は、常にサニタイジングされて渡されます。

以下サンプルコードを実行してみましょう。

```typescript:app.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  public getMessage() { return '<h1>hello, world!</h1>'; };
}
```
```html:app.component.html
{{getMessage()}}
```

hello, world!が大きく表示されるのではなく、h1タグがそのまま表示されましたね。
このように、サニタイジングされます。

---
[メニューに戻る](https://qiita.com/shuji-k/items/3b3cdec4dac3dc48ba43)