【Angular】Angular Materialでのローディングスピナー

 時間のかかるAPIを呼び出す場合等にユーザーに処理中であることを通知したい場合、1つの案としてローディングスピナーがあります。ローディングスピナーを出しておけば処理中にユーザが他の操作をすることも予防できます。

 今回はAngular Materialを使ってローディングスピナーを実装していきます。

 完成しているソースは下記にあります。

Angular-sample/loading-spinner at main · tsuneken5/Angular-sample
Contribute to tsuneken5/Angular-sample development by creating an account on GitHub.

 2014/9/14 : 解説を追記

環境

  • node: 18.13.0
  • Angular CLI:15.0.0
  • Angular Material:15.2.9

プロジェクトの作成

$ ng new loading-spinner

Angular Materialのインストール

$ ng add @angular/material

コンポーネントの生成

$ ng generate component spinner

モジュールのインポート

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { SpinnerComponent } from './spinner/spinner.component';

import { OverlayModule } from '@angular/cdk/overlay'; // 追加
import { PortalModule } from '@angular/cdk/portal';   // 追加
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';  // 追加

@NgModule({
  declarations: [
    AppComponent,
    SpinnerComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    OverlayModule,  // 追加
    PortalModule,   // 追加
    MatProgressSpinnerModule  // 追加
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

 OverlayModulePortalModuleMatProgressSpinnerModule をインポートします。

 また、 entryComponents にローディングスピナーのコンポーネントを追加しておきます。

 2024/9/14 : entryComponents はAngular9から非推奨になっています。なくても問題ないため削除します。

ローディングスピナーの実装

<div>
  <mat-progress-spinner mode="indeterminate"></mat-progress-spinner>
</div>

 ローディングスピナーを表示するコンポーネントを作成します。このページ単体だと以下のように画面の右上にスピナーが表示される画面になります。

ローディングスピナーの表示

<button (click)="click()">click</button>
import { Component } from '@angular/core';

import { Overlay } from '@angular/cdk/overlay';
import { ComponentPortal } from '@angular/cdk/portal';
import { SpinnerComponent } from './spinner/spinner.component';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'loading-spinner';

  private overlayRef = this.overlay.create({
    hasBackdrop: true,
    positionStrategy: this.overlay
      .position().global().centerHorizontally().centerVertically()
  });

  constructor(private overlay: Overlay) { }

  click() {
    this.overlayRef.attach(new ComponentPortal(SpinnerComponent));

    setTimeout(() => {
      this.overlayRef.detach();
    }, 3000);
  }
}

 2024/9/14 : 解説修正

 overlay.create() でOverlayRefインスタンスを作成します。OverlayRefとは簡単に言ってしまうとオーバーレイを管理するためのものです。 overlay.create() のコンフィグオプションは以下の通りです。

  • hasBackdrop :オーバーレイ表示時にオーバーレイ要素の下に全画面の層を挿入する機能です。これがないとオーバーレイの下の要素のボタンなどをクリックすることができてしまうので true に設定します。
  • position() :オーバーレイの表示位置を設定します。
  • global() :表示位置を画面の絶対位置で指定します。
  • centerHorizontally() :水平方向で中央寄せにします。
  • centerVertically() :垂直方向で中央寄せにします。
  • attach(Portal) :指定したポータルを呼び出します。
  • detach() :ポータルを削除します。

ポータルとは

 ポータルとは、ページ上に動的に表示できるUIの一部です。今回はスピナーを表示するコンポーネントをポータルにしています。

確認

$ ng serve

 ブラウザから「http://localhost:4200/」にアクセスすると確認できます。

 「click」ボタンを押下すると、3秒間ローディングスピナーが表示されます。

コメント

タイトルとURLをコピーしました