我正在开展一个项目并且一切运行良好......当我向API请求某些内容时(如下例所示),它显然只发送一个请求:
this.httpClient.get<MyInterface>('my_api').subscribe(data => this.items = data);
但是我想在新的HttpClient中利用拦截器,所以我开始搜索示例,然后找到了this。
我已经定义了帖子中的所有内容:
进展-interceptor.ts :
@Injectable()
export class ProgressInterceptor implements HttpInterceptor {
progress$: Observable<number | null>;
private progressSubject: Subject<number | null>;
constructor() {
this.progressSubject = new ReplaySubject<number | null>(1);
this.progress$ = this.progressSubject.asObservable();
}
intercept<T>(req: HttpRequest<T>, next: HttpHandler): Observable<HttpEvent<T>> {
const reportingRequest = req.clone({ reportProgress: true });
const handle = next.handle(reportingRequest);
handle.subscribe((event: HttpEvent<T>) => {
switch (event.type) {
case HttpEventType.Sent:
this.progressSubject.next(undefined);
break;
case HttpEventType.DownloadProgress:
case HttpEventType.UploadProgress:
if (event.total) {
this.progressSubject.next(Math.round((event.loaded / event.total) * 100));
}
break;
case HttpEventType.Response:
this.progressSubject.next(100);
break;
default:
break;
}
});
return handle;
}
}
进展-component.ts :
export class ProgressComponent implements OnInit {
progressPercentage$: Observable<number>;
@Input() color: ProgressBarColor = 'primary';
@ViewChild(MdProgressBar) private progressBar: MdProgressBar;
constructor(private interceptor: ProgressInterceptor) { }
ngOnInit(): void {
this.progressPercentage$ = this.interceptor.progress$
.map(progress => {
if (isNil(progress)) {
this.setMode('indeterminate');
return 0;
} else {
this.setMode('determinate');
return progress;
}
});
}
private setMode(mode: ProgressBarMode) {
this.progressBar.mode = mode;
}
}
app.module.ts :
const interceptor = new ProgressInterceptor();
@NgModule({
// ...
providers: [
{ provide: ProgressInterceptor, useValue: interceptor },
{ provide: HTTP_INTERCEPTORS, useValue: interceptor, multi: true }
]
})
问题是:现在,使用这个拦截器,当我做任何请求时,它会两次点击API。为什么?我怀疑是因为subscribe
intercept()
内的ProgressInterceptor
。
如何解决这个问题?
答案 0 :(得分:3)
您的猜测是正确的,通过订阅拦截器内的句柄,您再次触发可观察链,从而再次触发API调用。
在您的情况下,相应的运算符为library = [
{title: "Hitch Guide", by: "Doug", cats: ["comedy", "fiction", "british"]},
{title: "P and P", by: "Jane", cats: ["morality", "fiction", "british"]},
{title: "Searchin'", by: "Chad", cats: ["non-fiction", "morality", "gps"]},
{title: "Crazy Ben", by: "Walt", cats: ["non-fiction", "comedy", "dads"]}
]
# => [{:title=>"Hitch Guide", :by=>"Doug", :cats=>["comedy", "fiction", "british"]},
# {:title=>"P and P", :by=>"Jane", :cats=>["morality", "fiction", "british"]},
# {:title=>"Searchin'", :by=>"Chad", :cats=>["non-fiction", "morality", "gps"]},
# {:title=>"Crazy Ben", :by=>"Walt", :cats=>["non-fiction", "comedy", "dads"]}]
library.each_with_object({}) do |g,h|
title = g[:title]
g[:cats].each { |c| (h[c] ||= []) << title }
end
#=> {"comedy"=>["Hitch Guide", "Crazy Ben"],
# "fiction"=>["Hitch Guide", "P and P"],
# "british"=>["Hitch Guide", "P and P"],
# "morality"=>["P and P", "Searchin'"],
# "non-fiction"=>["Searchin'", "Crazy Ben"],
# "gps"=>["Searchin'"],
# "dads"=>["Crazy Ben"]}
(see the docs),因为您只想观察链内发生的事情,但无意操纵其中的任何内容。
看起来应该是这样的:
Node, X, Y, Z, Stress_data
1, 1.0, 1.0, 1.0, 123
2, 2.0, 2.0, 2.0, 234
3, 3.0, 3.0, 3.0, 345
...
Faces
1, 2, 3
3, 4, 5
...