|||||||||||||||||||||

なんぶ電子

- 更新: 

Angular Materialで処理中の待ち受け画面

angular login page

前回はAngularでRouter Outletに表示させた子コンポーネントでログイン処理中の画面を実装をしましたが、コードの省力化を考えてルートコンポーネントに持っていきます。

Router Outlet部に表示した子コンポーネントから親コンポーネントの変数を直接変更するのはルールに反していて、またイベントも伝える方法が(筆者には)見当たりません。

そこで、サービスとRxJSを使って実現してみました。

ここでは処理中画面の機能ですが、Router Outletの子コンポーネントから親コンポーネントにデータを渡したい場合にも応用ができると思います。

サービスの作成

まず処理中用のサービスのloadingServiceをつくり、Subjectオブジェクトを追加します。SubjectオブジェクトはObservableのobserverに相当し、nextを使って値を流すことができます。

PS> ng genarate sarvice loading

loading.service.ts

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
  
@Injectable({
  providedIn: 'root'
})
export class LoadingService {
  
  subject = new Subject<string>(); 
  
  constructor() { }
  
  setLoading(strMessage: string): void {
    this.subject.next(strMessage);
  }
}

ルートコンポーネントの修正(スクリプト)

おそらく、ルートコンポーネントではngOnInitをimplementsしていないので、その記述を加えた上で、ngOnInitを設定します。

次にルートコンポーネントにLoadingServiceを設定し、Observableオブジェクトを定義します。これはサービスにあるsubjectから生成しています。

Observableオブジェクトは内部にobserverを持ち、初期化時の関数でその挙動を事前に設定するものでした。subjectオブジェクトの場合はobserverを直接操作するのに加え、それに相当するObservableオブジェクトも同時に持つものです。

つまりsubjectでnextを使ってデータを渡すと、asObservableで返るObservableオブジェクトにデータを流すことになります。

app.component.ts


  import { Component, OnInit } from '@angular/core';
  ...
  import { Observable } from 'rxjs';
  import { switchMap } from 'rxjs/operators';
  import { LoadingService } from './loading.service';
  ...
  loading$: Observable<string> = this.loadingService.subject.asObservable();
  strMsg:string="";
  
  export class AppComponent implements OnInit{
    ...
    constructor(private loadingService: LoadingService) { }
    ...
    ngOnInit(): void {
      ...
      this.loading$.subscribe(
        (value: string) => { this.strMsg=value; }
      );
      ...
    }
  }
  ...

ルートコンポーネントの修正(HTML)

待ち受けの画面の部分を記述します。HTMLではstrMsgに文字が入っているときに表示するように設定します。mat-spinnerはAngular Materialで使える処理中画像です。

app.component.html

...
<div *ngIf="strMsg!==''" class="loading">
  <div class="loading-inner">
    <mat-spinner></mat-spinner>
    {{strMsg}}
  </div>
</div>
...

ルートコンポーネントの修正(CSS)

処理中の画面はCSSでposition: fixedを使って通常の画面から外して画面全体に表示させます。

app.component.css

...
.loading {
  display: table;
  width: 100%;
  height: 100%;
  position: fixed;
  top: 0;
  left: 0;
  background-color: #fff;
  opacity: 0.8;
  z-index: 1;
}

.loading-inner {
  display: table-cell;
  text-align: center;
  vertical-align: middle;
}

mat-spinner {
  margin: 0 auto;
}
...

子コンポーネントから設定

子コンポーネントでは、Loadingサービスを設定しサービスのsetLoadingに文字列をセットすることで表示、ブランクをセットすることで消去することができます。

any.compornent.ts


  ...
  constructor(private loadingService: LoadingService) { }
  ...
  showLoading(strMessage: string):void {
     //処理中の画面を表示させます
     this.loadingService.setLoading(strMessage);
  }
  hideLoading():void {
     //処理中の画面を消します
     this.loadingService.setLoading("");
  }
  ...

筆者紹介


自分の写真
がーふぁ、とか、ふぃんてっく、とか世の中すっかりハイテクになってしまいました。プログラムのコーディングに触れることもある筆者ですが、自分の作業は硯と筆で文字をかいているみたいな古臭いものだと思っています。 今やこんな風にブログを書くことすらAIにとって代わられそうなほど技術は進んでいます。 生活やビジネスでPCを活用しようとするとき、そんな第一線の技術と比べてしまうとやる気が失せてしまいがちですが、おいしいお惣菜をネットで注文できる時代でも、手作りの味はすたれていません。 提示されたもの(アプリ)に自分を合わせるのでなく、自分の活動にあったアプリを作る。それがPC活用の基本なんじゃなかと思います。 そんな意見に同調していただける方向けにLinuxのDebianOSをはじめとした基本無料のアプリの使い方を紹介できたらなと考えています。

広告