【问题标题】:angular 2/5 loading indicator while xhr request is in progressxhr 请求正在进行时的角度 2/5 加载指示器
【发布时间】:2018-03-14 10:38:40
【问题描述】:

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

我想创建一个紧凑的解决方案,我可以在多个项目中反复使用它,占用空间少,额外工作量最少。为了这个目标,我决定在被点击的按钮内实现加载指示器。

例如,如果按钮的标题为“SAVE”,则单击此按钮后,我希望该按钮在“SAVE”一词旁边显示一个微调器图标,同时会发生以下情况:

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

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

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

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

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

我知道 XHR 部分和 angular 的(点击)事件的东西。

我需要帮助的地方是管理该微调器的出现和消失以及使该按钮处于活动或不活动状态......

我知道解决方案是围绕 ngStyle、ngClass、mat-icons 和按钮的 [disabled] 指令,但我无法完全理解它。

【问题讨论】:

  • 你已经知道困难的部分,所以一步一步开始
  • 当然,我可以自己完成这件事……但这需要研发和时间,而且我在项目中还有很多其他事情要做。现在stackoverflow真的溢出了吗?
  • SO 不是免费的编码服务,适用于您没有时间的项目部分 - 它适用于您尝试某事并遇到特定问题/一段代码的地方
  • 而且很大一部分的 SO 问题都是这样的。 “多数人”首先解释失败的方法(添加 0 值)来提问只是为了证明像你这样的人已经完成了他/她的工作。继续...
  • 我已经找到了答案,但我想改进一下,我想我不应该分享它。 SO 不是免费的编码服务... :) 到底是谁要求的?

标签: css angular


【解决方案1】:

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

从 Angular 的角度来看,这里有几件事:

  • 您的按钮带有 (click) 处理程序和 [disabled] 属性,
  • 某种<div class="spinner"/>标签,
  • 调用某个后端的服务。

现在,算法是:

  • “加载”开始时,禁用按钮并显示微调器,
  • “加载”结束时,重新启用按钮,隐藏微调器。

所以,让我们假设您的服务是微不足道的:

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

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

它将返回一个 observable,它要么成功,要么失败(或挂起,但这是一个 different 问题)。

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

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

现在,您的组件必须加载结果并处理它们。但如果我们已经在进行加载,则不会。因此,它还可以更新“加载”属性。

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>

现在你应该准备好了。

编辑:根据您的评论,您的微调器位于 &lt;button&gt; 标记本身内。此外,您想使用 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>

【讨论】:

  • Ziatko,非常感谢您的详细回答,我相信当它被这样分解时,它会帮助很多人......我看到你如何使用 [disabled]按钮以及它与加载布尔值的关系。这回答了我的一个问题,即如何在 XHR 飞行时禁用按钮。但是,我试图将微调器放在按钮文本中,以最小化足迹。如果按钮说 100px 并且单词 SAVE 说 50px 我们仍然有另外 50pc 来放置一个微型微调器,以防止页面的其余部分受到影响。你是怎么做到的?
  • 我为此目的找到了这个解决方案...
  • 如果你用这个更新你的答案,我想把它称为完整并选择它作为接受的答案。
  • @newbyJoe 我已经添加了您的示例和其他示例。
  • 另外,对于投反对票的人,能否请我提示一下投反对票的原因,以便我以后可以尝试改进我的答案?
猜你喜欢
  • 1970-01-01
  • 2018-08-27
  • 1970-01-01
  • 1970-01-01
  • 2015-06-04
  • 1970-01-01
  • 2017-01-04
  • 1970-01-01
  • 2015-05-03
相关资源
最近更新 更多