【Angular小贴士】尝试使用Angular Material的加载旋转器

首先

如果需要调用耗时的API等情况下,希望向用户通知正在处理中,作为一种方案可以使用加载图标。
加载图标具有以下效果。

    • ユーザーに処理中であることを通知することによるユーザビリティ向上

 

    • 処理中にユーザーが他の操作をすることの防止

 

    ボタン連打による二重処理の防止

我想使用Angular的官方UI库-Angular Material来实现加载动画。

安装Angular Material

在安装上使用Angular CLI命令ng add。

ng add @angular/material

请参考官方指南,其中详细内容已有所说明。

引入模块

导入MatProgressSpinnerModule模块到模块中。

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; //<--追加

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

@NgModule({
  declarations: [
    AppComponent,
    LoadingSpinnerComponent,
    LoadingSpinnerCustomComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    MatProgressSpinnerModule  //<--追加
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

实现Loading Spinner

我将创建一个服务类来控制加载微调器的组件和其显示。

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

  /** スピナーの表示、非表示フラグ */
  public isLoading: Subject<boolean> = this.loadingSpinnerService.isLoading;

  constructor(private loadingSpinnerService: LoadingSpinnerService) {}

}
<div *ngIf="isLoading | async" class="overlay">
    <mat-progress-spinner class="spinner" mode="indeterminate"></mat-progress-spinner>
</div>

mat-progress-spinner标签的mode属性指定了加载旋转器的样式。
提供了以下两种样式。

    • determinate(デフォルト):指定した%の進行状況を表示する形式

 

    indeterminate:スピナーが常に周り続ける形式

由于determinate会涉及到进度更新等繁杂处理,所以我们将使用indeterminate。

@Injectable({
  providedIn: 'root'
})
export class LoadingSpinnerService {
  /** スピナーの表示、非表示フラグ */
  public isLoading: Subject<boolean> = new Subject<boolean>();

  constructor() { }

  /**
   * スピナーの表示
   */
  public show(): void {
    this.isLoading.next(true);
  }

  /**
   * スピナーの非表示
   */
  public hide(): void {
    this.isLoading.next(false);
  }
}

当显示或隐藏Spinner时,请调用以下方式来调用服务类的show和hide函数。
将隐藏处理实现在finalize中是为了无论API是正常还是错误响应,都能解除隐藏。

  onClick(){
    // スピナー表示
    this.loadingSpinnerService.show();

    // API呼び出しの仮実装(5秒間待機する)
    of().pipe(delay(5000),finalize(()=>{
      // スピナー非表示
      this.loadingSpinnerService.hide();
    })).subscribe();
  }

当实施后,按下按钮会显示加载图标,具体效果如下。

スピナー.gif

加载旋转器的个性化定制

スピナーカスタム.gif

总结

这次我尝试使用Angular Material来实现加载动画。
Angular Material不仅包括加载动画,还提供了各种其他UI组件,我也想尝试使用其他的组件。

这次的样品已在Github上发布。

只是随便说一下,相比于Vue.js和React,我觉得Angular Material这个UI库很有趣,因为它是官方提供的。
它的安装也很简单,而且有很好的指南(虽然没有日语版),可以快速创建Material Design风格的界面。
需要注意的是,当更新Angular时也需要更新Angular Material。
Angular每半年发布一个新版本,而Angular Material也会在同一时间发布。

bannerAds