abd*_*hab 5 rxjs angular angular-httpclient
如何利用 Angular HTTPClient 的progress
事件来显示不一定是文件请求的 Get 请求的百分比进度?
当前 HTTPClient 的progress
事件在请求完成后触发。我希望Content-Length
在后端工作并确定前端加载的内容百分比。
我正在为网格加载大量行,并且需要在 UI 上显示增量进度。是否可以?
我知道这个问题比较老,但是,我在寻找类似问题的答案时偶然发现了这个问题,由于没有公认的答案,我发布了我的解决方案。
我最近实现了一种通用方式来为每个请求显示一个进度条,而不管 angular 8 中的类型是什么。
首先,我创建了一个HttpInterceptor
它会自动拦截每个 http 调用,其中该reportProgress
选项设置为true
.
@Injectable()
export class HttpProgressInterceptor implements HttpInterceptor {
constructor(
private spinnerService: SpinnerService // my personal service for the progress bar - replace with your own
) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (req.reportProgress) {
// only intercept when the request is configured to report its progress
return next.handle(req).pipe(
tap((event: HttpEvent<any>) => {
if (event.type === HttpEventType.DownloadProgress) {
// here we get the updated progress values, call your service or what ever here
this.spinnerService.updateGlobalProgress(Math.round(event.loaded / event.total * 100)); // display & update progress bar
} else if (event.type === HttpEventType.Response) {
this.spinnerService.updateGlobalProgress(null); // hide progress bar
}
}, error => {
this.spinnerService.updateGlobalProgress(null); // hide progress bar
})
);
} else {
return next.handle(req);
}
}
}
Run Code Online (Sandbox Code Playgroud)
您需要在您module
的课程中注册此拦截器:
@NgModule({
declarations: [
AppComponent,
...
],
imports: [
BrowserModule,
...
RouterModule.forRoot(appRoutes)
],
providers: [
...
{ provide: HTTP_INTERCEPTORS, useClass: HttpProgressInterceptor, multi: true },
...}
],
bootstrap: [AppComponent]
})
export class AppModule { }
Run Code Online (Sandbox Code Playgroud)
基本上我们到这里就完成了,剩下的就是我们需要改变我们调用 api 的方式。如果您希望使用此拦截器监视特定请求,则需要告诉 angular 报告 HttpRequest 的进度:
@Injectable()
export class MyService {
constructor(
private http: HttpClient
) {}
myGetMethod() {
const url = "api/data/load/big/data";
const req = new HttpRequest("GET", url, {
reportProgress: true // this is important!
});
return this.http.request(req);
}
}
Run Code Online (Sandbox Code Playgroud)
这种调用httpClient
api 的方式在调用时会传递一个不同的对象,.subscribe
因此我们在调用时需要注意myGetMethod()
:
ngOnInit() {
this.myService.myGetMethod().subscribe((event: HttpEvent<any>) => {
if (event.type === HttpEventType.Response) {
const responseData = event.body;
console.dir(responseData); // do something with the response
}
});
}
Run Code Online (Sandbox Code Playgroud)
我们也可以在这里监听HttpEventType.DownloadProgress
事件并更新这个组件内的进度值——但这不是我的例子的重点。
提示:如果您遇到event.total
未定义的问题- 您必须检查您的 REST 后端是否真的提供了Content-Length
标题 - 如果缺少此标题,您将无法计算进度!
无论如何,我希望这有一天会帮助某人
那这个呢:
import { HttpEventType, HttpClient, HttpRequest} from '@angular/common/http';
Run Code Online (Sandbox Code Playgroud)
...
const request = new HttpRequest('GET', url, {
reportProgress: true
});
http.request(request).subscribe(event => {
// progress
if (event.type === HttpEventType.DownloadProgress) {
console.log(event.loaded, event.total);
// event.loaded = bytes transfered
// event.total = "Content-Length", set by the server
const percentage = 100 / event.total * event.loaded;
console.log(percentage);
}
// finished
if (event.type === HttpEventType.Response) {
console.log(event.body);
}
})
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
11308 次 |
最近记录: |