SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

次世代Webアプリケーションフレームワーク「Angular」の活用

「Angular」17の新機能を解説──シンプルで使いやすい記法が多数登場!

次世代Webアプリケーションフレームワーク「Angular」の活用 第28回

  • X ポスト
  • このエントリーをはてなブックマークに追加

条件分岐や繰り返しを簡潔に記述できるテンプレートの新記法

 これまでAngularで利用されていたngIfやngForといったディレクティブに代わって、Angular 17ではテンプレートで条件分岐や繰り返しをより簡潔に記述できる、新しい記法が導入されました。新旧記法を比べながら以下で説明していきます。

条件分岐1(if、else)

 図3は、チェックボックスのチェック有無をもとに表示を切り替えるサンプルです。

図3 条件分岐(if、else)のサンプル(p001-if)
図3 条件分岐(if、else)のサンプル(p001-if)

 この条件分岐を従来の記法で記述するとリスト1の通りになります。(1)の*ngIfディレクティブの設定で条件(isChecked)と、条件に合致しないときに表示する要素(2)の指定(else isNotChecked)を記述します。

[リスト1]従来の条件分岐(if、else)の記法(p001-if/src/app/app.component.html)
<div *ngIf="isChecked; else isNotChecked"> <!--(1)-->
  私のスマホはAndroidです。
</div>
<ng-template #isNotChecked> <!--(2)-->
  <div>私のスマホはAndroidではありません。</div>
</ng-template>

 同じ内容を新しい記法で記述するとリスト2の通りになります。@ifと@elseで条件に合致したときとしないときの表示内容を記述します。

[リスト2]新しい条件分岐(if、else)の記法(p001-if/src/app/app.component.html)
@if (isChecked) {
  <div>私のスマホはAndroidです。</div>
} @else {
  <div>私のスマホはAndroidではありません。</div>
}

条件分岐(switch、case)

 図4は、テキストボックスの入力値から表示を切り替えるサンプルです。入力値が「Apple」なら「iPhone」、「Samsung」なら「Galaxy」、それ以外は「その他」と表示します。

図4 条件分岐(switch、case)のサンプル(p002-switch)
図4 条件分岐(switch、case)のサンプル(p002-switch)

 この条件分岐を従来の記法で記述するとリスト3の通りになります。ngSwitchディレクティブに変数名(vendorName)を指定して、ngSwitchCaseディレクティブで変数の値に対応した表示を、ngSwitchDefaultディレクティブでデフォルトの表示を記述します。

[リスト3]従来の条件分岐(switch、case)の記法(p002-switch/src/app/app.component.html)
<div [ngSwitch]="vendorName">
  私のスマホは:
  <span *ngSwitchCase="'Apple'">iPhone</span>
  <span *ngSwitchCase="'Samsung'">Galaxy</span>
  <span *ngSwitchDefault>その他</span>
</div>

 同じ内容を新しい記法で記述するとリスト4の通りになります。@switchに変数名(vendorName)を指定して、@caseで変数の値に対応した表示を、@defaultでデフォルトの表示を記述します。

[リスト4]新しい条件分岐(switch、case)の記法(p002-switch/src/app/app.component.html)
<div>
  私のスマホは:
  @switch (vendorName) {
    @case ('Apple') { <span>iPhone</span> }
    @case ('Samsung') { <span>Galaxy</span> }
    @default { <span>その他</span> }
  }
</div>

繰り返し(for)

 図5は、複数データのリストを繰り返し処理で表示するサンプルです。

図5 繰り返し(for)のサンプル(p003-for)
図5 繰り返し(for)のサンプル(p003-for)

 複数データのリストは、app.component.tsに、リスト5の通り定義されています。Arrayの型として指定されているPhoneは、文字列型のvendor(=会社名)とname(=機種名)を含むインタフェースです(詳細はサンプルコード参照)。

[リスト5]図5のサンプルで表示するデータ(p003-for/src/app/app.component.ts)
phoneList: Array<Phone> = [
  {
    'vendor': 'Apple',
    'name': 'iPhone 15'
  },
(略)
]

 リスト5のデータを表示する従来の記法はリスト6の通りです。

[リスト6]従来の繰り返し(for)の記法(p003-for/src/app/app.component.html)
<div *ngFor="let phone of phoneList; trackBy: trackByMethod">
  {{phone.vendor}}:{{phone.name}}
</div>

 リスト6では、ngForディレクティブの「let phone of phoneList」記述により、phoneList配列の要素をphone変数として参照し、<div>タグ内で表示します。「trackBy」は、配列要素を一意識別する方法を定義するメソッド(trackByMethod)の指定で、このメソッドはapp.component.tsにリスト7の通り実装されています。このメソッドでphone.nameを返却することで、name(=機種名)で配列要素を一意識別することを表します。ngForディレクティブでtrackByの指定は必須ではありませんが、指定しないと配列の変更時に(変更された要素だけでなく)すべての要素を書き換えるため、パフォーマンスが低下します。

[リスト7]trackByMethodの実装(p003-for/src/app/app.component.ts)
trackByMethod(index:number, phone:Phone) {
  return phone.name;
}

 一方、新しい記法はリスト8の通りです。@for内に「phone of phoneList」と記述して、リスト6同様にphoneList配列の要素をphoneとして参照します。「track phone.name」は、リスト6の「trackBy」に対応します。古い記法では一意識別に利用する要素を返却するメソッド名を指定しましたが、新しい記法では一意識別に利用する要素(ここではname)を直接指定できます。なお、古い記法と異なり、新しい記法では(パフォーマンスの低下を避けるため)trackの指定が必須となります。

[リスト8]新しい繰り返し(for)の記法(p003-for/src/app/app.component.html)
@for (phone of phoneList; track phone.name) {
  <div>{{phone.vendor}}:{{phone.name}}</div>
}

 以上、Angular 17で導入されたテンプレートの新記法を説明しました。@if、@forなどの新記法は、従来の記法と比較して、JavaScriptや他のプログラム言語の記法に近いことから、より容易に習熟でき、また、簡潔に記述できます。

コンポーネントの遅延読込を簡潔に記述できる@defer

 読込に時間がかかるコンポーネントを必要になるまで読み込まない遅延読込は、パフォーマンスの改善に効果的です。Angular 17では、コンポーネントの遅延読込を簡潔に記述できる「@defer」が導入されました。この利用法を、サンプルコード(p004-defer)で説明していきます。このサンプルは、遅延処理を含む3つのコンポーネントをルーターで切り替えるようになっています。遅延読込の効果を確認するには、各コンポーネントを表示後、Webブラウザーを再読込してください。

@deferの基本的な記述方法

 もっとも単純なサンプル1(図6)では、Webブラウザーを再読込すると、大きな画像を含むコンポーネントをロード完了するまでの間、「ロード中...」と表示されます。

図6 遅延読込のサンプル(p004-defer)
図6 遅延読込のサンプル(p004-defer)

 図6を表示するコンポーネント(Sample1Component)のテンプレートには、リスト9の通り記述します。

[リスト9]基本的な@deferの記述(p004-defer/src/app/sample1.component.html)
@defer () {  <!--(1)-->
  <app-pizza></app-pizza>
} @loading { <!--(2)-->
  ロード中...
} @error {   <!--(3)-->
  ロードエラー
}

 遅延読込させたい<app-pizza>コンポーネントを、(1)の通り@deferで囲んで記述します。(2)の@loadingにはロード中の、(3)の@errorにはロードエラー時の表示を記述します。この記述により、<app-pizza>コンポーネントが遅延読込され、読込完了するまでは@loadingに指定された「ロード中...」が表示されます。なお<app-pizza>コンポーネントは、読込に時間がかかるよう、テンプレート(pizza.component.html)内にサイズの大きな画像を埋め込んでいます(詳細はサンプルコードを参照)。

遅延読込のタイミングを制御する

 @deferでは、遅延読込のタイミングを制御する仕組みが提供されています。サンプル2(図7)では、画面が表示されてから5秒後に遅延読込を開始します。

図7 5秒後に遅延読込を開始するサンプル(p004-defer)
図7 5秒後に遅延読込を開始するサンプル(p004-defer)

 図7を表示するコンポーネント(Sample2Component)のテンプレートには、リスト10の通り記述します(@loading、@errorは省略)。@deferの引数「on timer(5s)」により、5秒後に遅延読込が開始されます。@placeholderには、読込開始前の表示を記述します。

[リスト10]5秒後に遅延読込を開始する@deferの記述(p004-defer/src/app/sample2.component.html)
@defer (on timer(5s)) {
  <app-pizza></app-pizza>
} @placeholder {
  (5秒後、ここにピザが表示されます)
}

 サンプル3(図8)では、ボタンクリックで遅延読込を開始します。

図8 ボタンクリックで遅延読込するサンプル(p004-defer)
図8 ボタンクリックで遅延読込を開始するサンプル(p004-defer)

 図8を表示するコンポーネント(Sample3Component)のテンプレートには、リスト11の通り記述します(@loading、@errorは省略)。@deferの引数「when startDisplay」により、startDisplay変数がtrueになった時に遅延読込が開始されます。なおこのサンプルでは、startDisplayの初期値はfalseで、ボタンクリック時にtrueになるよう実装されています(詳細はサンプルコードを参照)。

[リスト11]ボタンクリックで遅延読込を開始する@deferの記述(p004-defer/src/app/sample3.component.html)
@defer (when startDisplay) {
  <app-pizza></app-pizza>
}

 このように@deferでは、引数に「on」や「when」を指定して、遅延読込のタイミングを制御できます。詳細は公式ドキュメントも参照してください。

次のページ
SSR/SSGに関する改善

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
次世代Webアプリケーションフレームワーク「Angular」の活用連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト  吉川 英一(ヨシカワ エイイチ)

WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS Twitter: @yyamada(公式)、@yyamada/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/18959 2024/02/09 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング