我有一个非常简单的加载组件,订阅者会通知我要显示的页面,所以这是我的组件:
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
答案 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