我的加载组件仅以角度显示最终任务后

时间:2018-12-17 00:33:08

标签: angular

我有一个非常简单的加载组件,订阅者会通知我要显示的页面,所以这是我的组件:

loading.component.html

<div id="loading-wrapper" *ngIf="loading">
  <div id="loader"></div>
</div>

loading.component.ts

import {Component, OnDestroy, OnInit} from '@angular/core';
import {LoadingService} from "./loading.service";
import {Subscription} from "rxjs";

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

  loading: boolean = false;
  loadingSubscription: Subscription;

  constructor(private loadingService: LoadingService) {
  }

  ngOnInit() {
    this.loadingSubscription = this.loadingService.loadingStatus.subscribe((value) => {
      this.loading = value;
    });
  }

  ngOnDestroy(): void {
    this.loadingSubscription.unsubscribe();
  }


}

因此,在对服务进行某些更改时会通知我的组件,并显示一个加载屏幕。这工作得很好,但我有一个情况是加载屏幕仅在任务结束时加载。我还有另一个组件,在ngOnInit中,我致电:

ngOnInit() {
  this.service.startLoading();
  makeSomeLongTask();
  }

执行makeSomeLongTask(),并在所有执行之后显示loadingScreen。我该如何解决?

编辑1 这是我要加载组件的服务类:

import {Injectable} from '@angular/core';
import {Subject} from "rxjs";

@Injectable({
  providedIn: 'root'
})
export class LoadingService {

  private _loading: boolean = false;
  loadingStatus: Subject<boolean> = new Subject();

  get loading(): boolean {
    return this._loading;
  }

  set loading(value: boolean) {
    this._loading = value;
    this.loadingStatus.next(value);
  }

  startLoading() {
    this.loading = true;
  }

  stopLoading() {
    this.loading = false;
  }

  constructor() {
  }
}

解决方案

我解决了创建HTTP拦截器以显示加载屏幕的问题,请参见本教程:https://medium.com/@zeljkoradic/loader-bar-on-every-http-request-in-angular-6-60d8572a21a9

2 个答案:

答案 0 :(得分:0)

之所以会发生这种现象,是因为更改检测未通过您的加载组件运行。

对于您的问题,一个非常简单的解决方案是使用您的模板中angular本身提供的强大的$query = " Select GROUP_CONCAT(ID,' <br>' ORDER BY DATUM SEPARATOR ' ') AS ID, GROUP_CONCAT(FOOD_TYPE,' <br>' ORDER BY DATUM SEPARATOR ' ') AS FOOD_TYPE, GROUP_CONCAT(STORE_NAME,' <br>' ORDER BY DATUM SEPARATOR ' ') AS STORE_NAME, GROUP_CONCAT(LOCATION,' <br>' ORDER BY DATUM SEPARATOR ' ') AS LOCATION, GROUP_CONCAT(DATUM,' <br>' ORDER BY DATUM SEPARATOR ' ') AS DATUM, GROUP_CONCAT(COST,' <br>' ORDER BY DATUM SEPARATOR ' ') AS COST FROM ( SELECT food.ID, food.FOOD_TYPE, food.STORE_NAME, food.LOCATION, food.DATUM, food.COST FROM food ) TEST group by DATUM ORDER BY DATUM DESC"; 运算符:

async

现在您不必订阅可观察的加载,因为异步管道正在为您处理所有事情(包括ChangeDetection)。

<div id="loading-wrapper" *ngIf="loadingObs | async">
  <div id="loader"></div>
</div>

答案 1 :(得分:0)

我看到两个选择:

1)创建一个Web服务,用于执行makeSomeLongTask()

内部的逻辑

2)使用Service workers

免责声明:

请参见上面链接中的prerequisites

  

您的应用程序必须在支持服务的Web浏览器中运行   工人。当前,最新版本支持服务人员   Chrome,Firefox,Edge,Safari,Opera,UC浏览器(Android   版本)和Samsung Internet。 IE和Opera Mini等浏览器不会   提供支持。要了解有关其他浏览器的更多信息   服务人员已准备就绪,请参阅“我可以使用”页面和MDN文档

免责声明[2]:

我没有在Angular应用程序中单独使用Service worker,但它看起来像是其中一种选择。

编辑 ...还有第三种选择(我不推荐),Simon K在评论中提到了

ngAfterViewInit(): void {
    setTimeout(function () {
        makeSomeLongTask();
    }, 0);
}

只需尝试在其他lifecycle hook中运行它即可。实施AfterViewInit