在 api 调用时显示组件
Displaying a component upon an api call
我有一个用于加载屏幕的组件。我想在 api 通话期间展示它。
正在加载-screen.component.html
<div *ngIf="isLoading | async" class="overlay">
//Some html for the loading screen.
</div>
正在加载-screen.component.ts
isLoading: Subject<boolean> = this.loaderService.isLoading;
顺便说一下,当我将 isLoading 设置为真正的硬编码时,组件淡入并且我看到了我应该看到的加载屏幕。所以我假设这个组件没有任何问题。
正在加载-screen.interceptor.ts
@Injectable()
export class LoaderInterceptor implements HttpInterceptor {
constructor(public loaderService: LoadingScreenService) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.loaderService.show();
return next.handle(req).pipe(
finalize(() => this.loaderService.hide())
);
}
}
我没有共享 api 调用,但它不是必需的,因为我看到在调试时进行 api 调用时触发了 show() 和 hide() 方法。
正在加载-screen.service.ts
@Injectable({
providedIn: 'root'
})
export class LoadingScreenService {
isLoading = new Subject<boolean>();
constructor() { }
show() {
this.isLoading.next(true);
}
hide() {
this.isLoading.next(false);
}
}
app.module.ts
providers: [
LoadingScreenService,
{ provide: HTTP_INTERCEPTORS, useClass: LoaderInterceptor, multi: true }
]
进行以下更改,您就可以开始了,
加载中-screen.component.ts
loadingFlag : boolean;
constructor(private loaderService:loaderService){
this.loaderService.subscribe(value => (this.loadingFlag = value));
}
正在加载-screen.component.html
<div *ngIf="loadingFlag" class="overlay">
//Some html for the loading screen.
</div>
My First Answer in Whosebug.
试试看
在 LoadingScreenService 上将其类型从 Subject 更改为 BehaviourSubject 类型并从登录组件订阅它
在加载服务上添加一个 BehaviourSubject
isLoading:BehaviourSubject = new BehaviourSubject<boolean>();
在组件构造器或ngOnInit中添加订阅
this.loadingService.isLoading.subscribe(res=>{
this.isLoading = res;
});
希望对您有所帮助
我发现了问题。似乎我在 app.component.ts 中留下了提供者描述,它搞砸了一切,甚至没有给出错误。我的错。
将加载作为布尔值处理过于简单化了问题。我认为更好的方法是使用 Promise
数组并检查它的长度,其中每个 promise 代表正在加载的异步任务,因此只有在任务数组为空或任务超时时才删除加载指示器(或任何其他 completion/cancelation 逻辑)。
class LoadingService {
runningTasks : Promise[] = [];
addTask(promise:Promise) {
//push to array and set timeout
//await success/error to remove task
}
}
使用单独的广播服务
BroadcastService (broadcast.service.ts)
import { Injectable } from '@angular/core';
import { Subject, Subscription } from 'rxjs';
import { filter, map } from 'rxjs/operators';
@Injectable()
export class BroadcastService {
private handler: Subject<any> = new Subject<any>();
broadcast(type: string, action: any = null) {
this.handler.next({ type, action });
}
subscribe(type: string, callback: (action: any) => void): Subscription {
return this.handler
.pipe(
filter(info => info.type === type),
map(info => info.action)
)
.subscribe(callback);
}
}
此 class 充当整个应用程序的事件服务总线。 Class 不需要注册,因为它是在根级别注册的。可以注入组件。
Subscribe to events in app component
显示加载组件
this.broadcastService.subscribe('SHOW_lOADING_COMPONENT', ()=>{
this.isLoading= true;
});
隐藏加载组件
this.broadcastService.subscribe('HIDE_lOADING_COMPONENT', ()=>{
this.isLoading= true;
});
Publish events inside components or services
get<T>(path: string, params: HttpParams): Observable<T> {
this.broadcastService.broadcast('SHOW_lOADING_COMPONENT', null);
return this.httpClient
.get<T>(path, { headers: this.setHeaders(), params })
.pipe(catchError(err => {
this.broadcastService.broadcast('HIDE_lOADING_COMPONENT', null);
this.handleError(err);
return of<any>({ isSuccess: false, error: err });
})
);
}
In app.component.html
<div *ngIf="isLoading | async" class="overlay">
//Some html for the loading screen.
</div>
<router-outlet></router-outlet>
注意 :通过这种方式,您可以发布和订阅越来越多的事件,这些事件以可重用性和松散耦合的方式指导应用程序。
我有一个用于加载屏幕的组件。我想在 api 通话期间展示它。
正在加载-screen.component.html
<div *ngIf="isLoading | async" class="overlay">
//Some html for the loading screen.
</div>
正在加载-screen.component.ts
isLoading: Subject<boolean> = this.loaderService.isLoading;
顺便说一下,当我将 isLoading 设置为真正的硬编码时,组件淡入并且我看到了我应该看到的加载屏幕。所以我假设这个组件没有任何问题。
正在加载-screen.interceptor.ts
@Injectable()
export class LoaderInterceptor implements HttpInterceptor {
constructor(public loaderService: LoadingScreenService) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.loaderService.show();
return next.handle(req).pipe(
finalize(() => this.loaderService.hide())
);
}
}
我没有共享 api 调用,但它不是必需的,因为我看到在调试时进行 api 调用时触发了 show() 和 hide() 方法。
正在加载-screen.service.ts
@Injectable({
providedIn: 'root'
})
export class LoadingScreenService {
isLoading = new Subject<boolean>();
constructor() { }
show() {
this.isLoading.next(true);
}
hide() {
this.isLoading.next(false);
}
}
app.module.ts
providers: [
LoadingScreenService,
{ provide: HTTP_INTERCEPTORS, useClass: LoaderInterceptor, multi: true }
]
进行以下更改,您就可以开始了,
加载中-screen.component.ts
loadingFlag : boolean;
constructor(private loaderService:loaderService){
this.loaderService.subscribe(value => (this.loadingFlag = value));
}
正在加载-screen.component.html
<div *ngIf="loadingFlag" class="overlay">
//Some html for the loading screen.
</div>
My First Answer in Whosebug.
试试看 在 LoadingScreenService 上将其类型从 Subject 更改为 BehaviourSubject 类型并从登录组件订阅它
在加载服务上添加一个 BehaviourSubject
isLoading:BehaviourSubject = new BehaviourSubject<boolean>();
在组件构造器或ngOnInit中添加订阅
this.loadingService.isLoading.subscribe(res=>{
this.isLoading = res;
});
希望对您有所帮助
我发现了问题。似乎我在 app.component.ts 中留下了提供者描述,它搞砸了一切,甚至没有给出错误。我的错。
将加载作为布尔值处理过于简单化了问题。我认为更好的方法是使用 Promise
数组并检查它的长度,其中每个 promise 代表正在加载的异步任务,因此只有在任务数组为空或任务超时时才删除加载指示器(或任何其他 completion/cancelation 逻辑)。
class LoadingService {
runningTasks : Promise[] = [];
addTask(promise:Promise) {
//push to array and set timeout
//await success/error to remove task
}
}
使用单独的广播服务
BroadcastService (broadcast.service.ts)
import { Injectable } from '@angular/core';
import { Subject, Subscription } from 'rxjs';
import { filter, map } from 'rxjs/operators';
@Injectable()
export class BroadcastService {
private handler: Subject<any> = new Subject<any>();
broadcast(type: string, action: any = null) {
this.handler.next({ type, action });
}
subscribe(type: string, callback: (action: any) => void): Subscription {
return this.handler
.pipe(
filter(info => info.type === type),
map(info => info.action)
)
.subscribe(callback);
}
}
此 class 充当整个应用程序的事件服务总线。 Class 不需要注册,因为它是在根级别注册的。可以注入组件。
Subscribe to events in app component
显示加载组件
this.broadcastService.subscribe('SHOW_lOADING_COMPONENT', ()=>{
this.isLoading= true;
});
隐藏加载组件
this.broadcastService.subscribe('HIDE_lOADING_COMPONENT', ()=>{
this.isLoading= true;
});
Publish events inside components or services
get<T>(path: string, params: HttpParams): Observable<T> {
this.broadcastService.broadcast('SHOW_lOADING_COMPONENT', null);
return this.httpClient
.get<T>(path, { headers: this.setHeaders(), params })
.pipe(catchError(err => {
this.broadcastService.broadcast('HIDE_lOADING_COMPONENT', null);
this.handleError(err);
return of<any>({ isSuccess: false, error: err });
})
);
}
In app.component.html
<div *ngIf="isLoading | async" class="overlay">
//Some html for the loading screen.
</div>
<router-outlet></router-outlet>
注意 :通过这种方式,您可以发布和订阅越来越多的事件,这些事件以可重用性和松散耦合的方式指导应用程序。