在加载页面数据时,我实现了一个带有垫子旋转器的对话框.我使用的是ANGLE V14.我使用的是对话框,而不是普通的微调控件,因为我需要在其中传递一些信息.我遇到的问题是,对话框不会显示,除非我在它后面立即放置一个断点.我对Angular 的理解是同步的,所以显示对话框的代码应该在加载数据之前完成,对吗?不过,我还try 向LoadData方法添加setTimeout,以给它额外的时间.但该对话框从未出现.

该对话框是其自己的组件

<h3 mat-dialog-title>Please Wait</h3>

<mat-dialog-content>
  <div style="display:flex; flex-direction:row; justify-content:space-around ">
      We're getting your data...
    <mat-spinner [diameter]="20"></mat-spinner>
  </div>
</mat-dialog-content>

<mat-dialog-actions></mat-dialog-actions>

Typescript 文件为空

import { Component, OnInit } from '@angular/core';
import { MatDialog, MatDialogRef } from '@angular/material/dialog';

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

  constructor(
    public spinnerRef: MatDialogRef<SpinnerComponent>
  ) { }
 
  ngOnInit(): void {
  }

}

我正在将微调器和数据加载到组件ngOnInit中:

  ngOnInit(): void {

    this.showSpinner();
    setTimeout(() => this.loadData(), 3000);
    this.hideSpinner();
  }

以下是showSpner和hideSpner函数:

private showSpinner(): void {

    const spinnerConfig = new MatDialogConfig();
    spinnerConfig.disableClose = true;
    spinnerConfig.autoFocus = true;
    spinnerConfig.width = '400px';
    spinnerConfig.height = '150px';
    spinnerConfig.closeOnNavigation = false;
    spinnerConfig.disableClose = true;
    spinnerConfig.hasBackdrop = true;

    this.spinner.open(SpinnerComponent, spinnerConfig)
  }

  private hideSpinner(): void {
    this.spinner.closeAll()
  }

Load Data方法进行几个服务调用来获取下拉字段的数据.这是一个示例,总共有4个函数调用

  private loadData(): void {
    this.projectService.getAllProjects().subscribe((data) => {
      this.projects = data;
    }, (error) => {
      console.log("an error occured in the project service");
    })

推荐答案

问题是您没有等待加载数据的异步进程.这意味着该代码是同步执行的,但setTimeout方法内部的回调是异步执行的:

ngOnInit(): void {
  this.showSpinner();
  setTimeout(() => this.loadData(), 3000);
  this.hideSpinner();
}

因此,加载微调器将打开,但会立即再次关闭.

您可以通过等待loadData方法的结果来修复它.使用此代码时,执行将暂停,直到loadData方法返回结果:

async ngOnInit() {
  this.showSpinner();
  await this.loadData();
  this.hideSpinner();
}

但要实现这一点,您必须确保可以等待loadData方法.这可以按如下方式完成:

private async loadData() {
  const data = await lastValueFrom(this.projectService.getAllProjects());
  this.projects = data;
}

现在,我们正在等待我们的项目服务对RxJS操作员lastValueFrom的响应.这意味着它会一直等到从HTTP请求中获得最后一个值,在我们的例子中就是项目列表.通过使用关键字async,loadData方法自动返回我们的ngOnInit方法可以等待的promise .

StackBlitz Example

https://stackblitz.com/edit/angular-59cr8m?file=src/app/dialog-overview-example.ts

Angular相关问答推荐

如何使用新的@for遍历Angular 为17的对象?

MAT表的内联文本编辑-未刷新编辑图标

Angular中的Bootstrap carousel动态属性

角material 17 -如何从Style.scss中的主题中获取原色

使用jsPDF生成带有图像的PDF时出现灰色条纹

类是一个独立的组件,不能在Angular中的`@NgModule.bootstrap`数组中使用

角路径S异步旋转变压器仍可观察到

Angular 应用程序未在Azure应用程序服务中运行

Observable转换为Observable

以 Angular 形式添加动态控件失败

ng14中具有强类型表单的FormBuilder

带有 Angular 2 的 Django

使用 Jasmine 和 Karma 对 Angular 进行单元测试,错误:无法绑定到xxx,因为它不是xxxxxx的已知属性.

如何在 Angular 2 中正确设置 Http 请求标头

ngx-toastr,Toast 未在 Angular 7 中显示

Angular 4 设置下拉菜单中的选定选项

为什么 *ngIf 不适用于 ng-template?

如何将从后端渲染的参数传递给angular2 bootstrap 方法

如何将日期转换为Angular 2 中的yyyy-MM-dd格式

如果不判断 {{object.field}} 是否存在则出错