Angular 如何阻止UI直到所有挂起的操作完成?

Angular 如何阻止UI直到所有挂起的操作完成?,angular,ngx-spinner,Angular,Ngx Spinner,我有一个角度8网络应用程序与。我用它来阻止UI,当一些冗长的过程正在进行时,防止用户在某些部分尚未完全加载时与复杂表单交互 问题是,如果某些进程调用hide,NgxSpinner会立即隐藏自己,而不管是否还有另一个进程运行自己的show/hide调用对。因此,当任何较短的进程完成并调用了spinner.hide()时,网页被取消阻止的时间太早 下面是一个例子 如何使NgxSpinner等待最后一次隐藏以匹配所有显示调用? 另外,我尝试过的许多UI块库似乎都有问题——它们只是没有考虑到并行进程多次

我有一个角度8网络应用程序与。我用它来阻止UI,当一些冗长的过程正在进行时,防止用户在某些部分尚未完全加载时与复杂表单交互

问题是,如果某些进程调用
hide
,NgxSpinner会立即隐藏自己,而不管是否还有另一个进程运行自己的
show/hide
调用对。因此,当任何较短的进程完成并调用了
spinner.hide()
时,网页被取消阻止的时间太早

下面是一个例子

如何使NgxSpinner等待最后一次
隐藏
以匹配所有
显示
调用?


另外,我尝试过的许多UI块库似乎都有问题——它们只是没有考虑到并行进程多次调用
show/hide

你可以利用Promise。每个流程函数将返回一个承诺,然后您可以使用promise.all函数,一旦所有承诺都得到解决,就会调用该函数。可以在promise.all方法中隐藏微调器。 请在下面找到示例代码

this.spinner.show();
let p1 = new Promise((resolve, reject) => {

  setTimeout(() => {
    resolve();
  }, 3000);

});

let p2 = new Promise((resolve, reject) => {

  setTimeout(() => {
    resolve();
  }, 3000);

});

Promise.all([p1,p2]).then( ()=> {
  this.spinner.hide();
})

你可以利用诺言。每个流程函数将返回一个承诺,然后您可以使用promise.all函数,一旦所有承诺都得到解决,就会调用该函数。可以在promise.all方法中隐藏微调器。 请在下面找到示例代码

this.spinner.show();
let p1 = new Promise((resolve, reject) => {

  setTimeout(() => {
    resolve();
  }, 3000);

});

let p2 = new Promise((resolve, reject) => {

  setTimeout(() => {
    resolve();
  }, 3000);

});

Promise.all([p1,p2]).then( ()=> {
  this.spinner.hide();
})

您可能需要使用forkJoin操作符,在这种情况下,当所有请求完成时,您将进入此状态,然后您将隐藏加载微调器。您可能需要使用forkJoin操作符,在这种情况下,当所有请求完成时,您将进入此状态,然后将隐藏加载微调器

为微调器创建一个服务,并保持显示/隐藏计数

export class MySpinnerService {
  showIndex = 0;
  hideIndex = 0;

  constructor(private spinner: NgxSpinnerService) {}

  show() {
    this.showIndex++;
    this.spinner.show();
    console.log('show spinner', this.showIndex);
  }

  hide() {
    this.hideIndex++;
    if (this.showIndex === this.hideIndex) {
      this.spinner.hide();
      console.log('hide spinner', this.hideIndex);      
    }
  }
因此,当
showIndex
hideIndex
等于时,您需要隐藏微调器

调用您的组件

this.mySpinner.show(); // show spinner
this.mySpinner.hide(); // hide spinner

下面是一个例子

为微调器创建一个服务,并保持显示/隐藏计数

export class MySpinnerService {
  showIndex = 0;
  hideIndex = 0;

  constructor(private spinner: NgxSpinnerService) {}

  show() {
    this.showIndex++;
    this.spinner.show();
    console.log('show spinner', this.showIndex);
  }

  hide() {
    this.hideIndex++;
    if (this.showIndex === this.hideIndex) {
      this.spinner.hide();
      console.log('hide spinner', this.hideIndex);      
    }
  }
因此,当
showIndex
hideIndex
等于时,您需要隐藏微调器

调用您的组件

this.mySpinner.show(); // show spinner
this.mySpinner.hide(); // hide spinner

下面是一个例子

我认为,您可以在服务中添加一个计数器,在每次进程调用时递增,当它完成时递减。一旦为零,就可以调用spinner.hide()方法。希望你能理解。我无法访问Stackblitz页面。这是否回答了您的问题@感谢akpgp,它给出了关于引用计数实现的想法。我希望UI拦截器中会内置一些东西,但显然没有,我必须将NgxSpinner包装在我自己的refcounting服务中。我认为,您可以在服务中添加一个计数器,每次进程调用时递增,当它完成时递减。一旦为零,就可以调用spinner.hide()方法。希望你能理解。我无法访问Stackblitz页面。这是否回答了您的问题@感谢akpgp,它给出了关于引用计数实现的想法。我希望UI拦截器中会内置一些东西,但显然没有,我必须将NgxSpinner包装在我自己的refcounting服务中。不幸的是,在现实生活中并没有那么简单。我的StackBlitz代码是一个非常简单的例子。实际上,微调器在许多服务和组件中到处都显示和隐藏,我只想确保微调器在最后一次调用
hide
之前不会隐藏。不幸的是,在现实生活中并不是那么简单。我的StackBlitz代码是一个非常简单的例子。实际上,微调器在许多服务和组件中到处都显示和隐藏,我只想确保微调器在最后一次调用
hide
之前不会隐藏。不幸的是,在现实生活中并不是那么简单。我的StackBlitz代码是一个非常简单的例子。实际上,微调器在许多服务和组件中到处显示和隐藏,我只是想确保微调器在最后一次调用hide之前不会隐藏。不幸的是,在现实生活中并没有那么简单。我的StackBlitz代码是一个非常简单的例子。实际上,微调器在许多服务和组件中到处显示和隐藏,我只想确保微调器在最后一次调用hide之前不会隐藏。