当xhr请求正在进行时,角度2/5加载指示符

时间:2018-03-14 10:38:40

标签: css angular

当xhr请求正在进行时,有许多加载指示器的实现。有些会进行整页覆盖,有些会在屏幕上的指定位置显示消息,等等......

我想创建一个紧凑的解决方案,我可以在多个项目中一次又一次地使用它,只需0个足迹,并且可以进行额外的工作。为了达到这个目标,我决定在点击的按钮内实现加载指示器。

例如,如果按钮标题为" SAVE",点击此按钮后,我希望按钮在单词旁边显示一个微调器图标" SAVE& #34;而以下事情要发生:

1)按钮立即被禁用,因此忽略它上面的新点击。

2)一个加载指示器(一个旋转的gif)开始出现在单词" SAVE"的左边。并且这个微调器继续旋转,直到XHR回来并带有响应

3)当XHR响应时,按钮再次启用

由于微调器在按钮内发生,因此占用空间为0.由于微调器在按钮内发生,因此在HTML中创建特殊的<div>没有任何开销。

有人可以与我分享我需要学习的主题吗?

我知道XHR部分和角度(点击)事件的内容。

我需要帮助的是管理那个微调器出现和消失,并使该按钮处于活动或非活动状态......

我知道解决方案是在ngStyle,ngClass,mat-icons和按钮的[disabled]指令的某处,但是无法解决它。

1 个答案:

答案 0 :(得分:2)

正如评论中所提到的,你知道困难的部分。但是,让我们完成这些步骤。

从Angular的角度来看,这里有一些事情:

  • 您的按钮包含(click)处理程序和[已禁用]属性
  • 某种<div class="spinner"/>标记,
  • 一个叫一些后端的服务。

现在,algorhytm是:

  • 当&#34; loading&#34;启动,禁用按钮并显示微调器,
  • 当&#34; loading&#34;结束,重新启用按钮,隐藏微调器。

所以,让我们假设你的服务很简单:

class MyService {
  constructor(private http: HttpClient) {}

  loadResults() {
    return this.http.get('/api/endpoint');
  }
}

它将返回一个可观察的,可以成功或失败(或挂起,但这是一个different问题。)

让我们解决我们的任务。首先,按钮(点击)处理程序:

<button (click)="getResults()">Get results</button>

现在,您的组件必须加载结果并处理它们。但是,如果我们已经在进行加载,那就不行了因此,它还可以更新&#34; loading&#34;属性。

getResults() {
  if (!this.loading) {
    return;
  }
  // otherwise set `loading` flag
  this.loading = true;
  this.myService.loadResults()
    .subscribe(results => this.results = results)
    // trigger this even if we fail
    // note: you might need to import finally operator
    .finally(() => this.loading = false); 
}

所以,现在我们在组件上有一个布尔loading标志。好的,让我们在组件,按钮和微调器上使用它。

<!-- set disabled property depending on the loading status -->
<button (click)="getResults()" [disabled]="loading">Get results</button>

<!-- add "hidden" class depending on the loading status -->
<div class="spinner" [ngClass]="{ hidden: loading }"></div>

现在你应该被设定。

修改:根据您的评论,您的微调器位于<button>标签内。此外,您希望使用HTML hidden属性,而不是hidden css类。这也是可能的,代码看起来像这样:

<button class="login-button" (click)="checkData()">
  <i [hidden]="!isLoading" class='material-icons'>spinner</i>
  <span [hidden]="isLoading">Log In <i class='material-icons'>arrow_forward</i></span>
</button>

或者,您甚至可以使用从DOM中完全删除元素

<button class="login-button" (click)="checkData()">
  <i *ngIf="loading" class='material-icons'>spinner</i>
  <span *ngIf="!loading">Log In <i class='material-icons'>arrow_forward</i></span>
</button>