如何为angular 5中的每个HTTP请求显示微调器?
我是新手。如何编写一个通用函数来显示angular 5中每个HTTP请求的微调器。请帮助我实现此功能。这与HttpClient或HTTP请求无关。这是一个如何处理一般异步调用(HTTP或非HTTP)的问题 你应该如何为angular 5中的每个HTTP请求显示微调器?,angular,angular-http,angular-http-interceptors,angular-httpclient,Angular,Angular Http,Angular Http Interceptors,Angular Httpclient,我是新手。如何编写一个通用函数来显示angular 5中每个HTTP请求的微调器。请帮助我实现此功能。这与HttpClient或HTTP请求无关。这是一个如何处理一般异步调用(HTTP或非HTTP)的问题 你应该 <div class="spinner" *ngIf="loading"; else showWhenLoaded"><div> <ng-template #showWhenLoaded> <div>Your Content<
<div class="spinner" *ngIf="loading"; else showWhenLoaded"><div>
<ng-template #showWhenLoaded>
<div>Your Content</div>
</ng-template>
您可以使用Angular来显示所有请求的微调器,下面是一个很好的示例
此外,您还必须创建一个微调器服务/模块,并将其注入http侦听器中。最后,在拦截方法中,可以使用Finally
rxJs方法停止微调器。下面是一个简单的实现:
intercept(req:HttpRequest您可以创建一个服务,然后在订阅它的应用程序的根级别向它发布事件。让我解释一下
broadcast.service.ts(这是您的服务)
在应用程序组件级别:
this.broadcastService.subscribe('PROGRESS_START', ()=>{
//hit when you start http call
this.myLoader = true;
});
最后,在app.component.html中:
<div *ngIf="myLoader">
<!--YOUR LOADER SHOULD GO HERE-->
</div>
<router-outlet></router-outlet>
这是一种非常通用的松耦合方式,可以实现您想要的任何加载程序。在Angular的拦截器中,我使用了“do”操作符
intercept(req:HttpRequest,next:HttpHandler):可观察{
//成功和失败响应的处理程序
const onReqFinish=(事件:HttpEvent)=>{
如果(event.type==4){
this.onXhrFinish();
}
};
这个.onXhrStart();
返回下一个句柄(req)
.做(
完成时,
onReqFinish
);
}
来源
创建服务
//loader.service.ts
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class LoaderService {
public isLoading = new BehaviorSubject(false);
constructor() { }
}
创建加载程序拦截器
// loader.interceptors.ts
import { Injectable } from '@angular/core';
import {
HttpErrorResponse,
HttpResponse,
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor
} from '@angular/common/http';
import { Observable } from 'rxjs';
import { LoaderService } from './loader.service';
@Injectable()
export class LoaderInterceptor implements HttpInterceptor {
private requests: HttpRequest<any>[] = [];
constructor(private loaderService: LoaderService) { }
removeRequest(req: HttpRequest<any>) {
const i = this.requests.indexOf(req);
if (i >= 0) {
this.requests.splice(i, 1);
}
this.loaderService.isLoading.next(this.requests.length > 0);
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.requests.push(req);
console.log("No of requests--->" + this.requests.length);
this.loaderService.isLoading.next(true);
return Observable.create(observer => {
const subscription = next.handle(req)
.subscribe(
event => {
if (event instanceof HttpResponse) {
this.removeRequest(req);
observer.next(event);
}
},
err => {
alert('error returned');
this.removeRequest(req);
observer.error(err);
},
() => {
this.removeRequest(req);
observer.complete();
});
// remove request from queue when cancelled
return () => {
this.removeRequest(req);
subscription.unsubscribe();
};
});
}
}
完整的指南包含一个materialmat ProgressSpinner
用法。非常酷!在这里,我编写了一些创建自定义progressbar的步骤
创建一个组件
//loader.interceptor.ts
import { Component, OnInit } from '@angular/core';
import { LoaderService } from '../loader.service';
@Component({
selector: 'app-loading',
templateUrl: './loading.component.html',
styleUrls: ['./loading.component.css']
})
export class LoaderComponent implements OnInit {
loading: boolean;
constructor(private loaderService: LoaderService) {
this.loaderService.isLoading.subscribe((v) => {
console.log(v);
this.loading = v;
});
}
ngOnInit() {
}
}
从“@angular/core”导入{Component,Input};
@组成部分({
选择器:“应用软件进度条”,
模板:
,
})
导出类SWProgresbarComponent{
@Input()加载=false;
构造函数(){}
}
2在模块中导入组件:-
import { SWProgresbarComponent } from '../sw-progressbar.component';
@NgModule({
declarations: [SWProgresbarComponent],
imports: [
CommonModule,
MaterialModule,
RouterModule
],
exports: [SWProgresbarComponent,
RouterModule
]
})
export class SharedModule { }
如何使用它
此处在要显示的组件中加载将为真
下面是要显示加载程序的组件中的代码
对于微调器,将“垫进度”微调器替换为“垫进度”微调器
创建拦截器服务
import { Injectable } from '@angular/core';
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Observable } from 'rxjs';
import { finalize } from 'rxjs/operators';
import { NgxSpinnerService } from 'ngx-spinner';
@Injectable()
export class SpinnerInterceptor implements HttpInterceptor {
constructor(private spinner: NgxSpinnerService) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.spinner.show();
return next.handle(req).pipe(
finalize(() => this.spinner.hide())
);
}
}
路由器插座内的最后一个in-app.component添加微调器标签
<router-outlet>
<ngx-spinner bdColor="rgba(0,0,0,0.8)"
size="medium"
color="#fff"
type="timer">
<p style="color: #fff"> Loading... </p>
</ngx-spinner>
</router-outlet>
加载
正如您所见,我使用的是NgxSpinner,但如果您使用自定义微调器,这应该没有什么区别,您只需要创建服务来显示和隐藏微调器,并将此服务注入微调器拦截器中。您可以使用PaceJs,它不是特定于角度的,但它是开箱即用的。我认为显示单个微调器不是一个好主意任何xhr请求的HTTP加载器。将来可能需要更多详细信息检查此示例教程,以使用拦截器显示单个或多个请求的HTTP加载器。他也可以实现NGRX,但这不是他所问的“为每个HTTP请求显示微调器的通用函数”。这样,他就可以从应用程序中的任何位置发布进度开始事件。这样,您将向应用程序引入多少加载程序?每个需要单独获取的项目一个加载程序。如果您获取的动态数据仅在screenProb的一部分中使用,则不需要使用加载程序阻止整个应用程序可复制的:
import { SWProgresbarComponent } from '../sw-progressbar.component';
@NgModule({
declarations: [SWProgresbarComponent],
imports: [
CommonModule,
MaterialModule,
RouterModule
],
exports: [SWProgresbarComponent,
RouterModule
]
})
export class SharedModule { }
import { Injectable } from '@angular/core';
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Observable } from 'rxjs';
import { finalize } from 'rxjs/operators';
import { NgxSpinnerService } from 'ngx-spinner';
@Injectable()
export class SpinnerInterceptor implements HttpInterceptor {
constructor(private spinner: NgxSpinnerService) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.spinner.show();
return next.handle(req).pipe(
finalize(() => this.spinner.hide())
);
}
}
import { HTTP_INTERCEPTORS } from '@angular/common/http';
....
@NgModule({
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: SpinnerInterceptor, multi: true }
]
})
<router-outlet>
<ngx-spinner bdColor="rgba(0,0,0,0.8)"
size="medium"
color="#fff"
type="timer">
<p style="color: #fff"> Loading... </p>
</ngx-spinner>
</router-outlet>