我想在发送Http请求时显示加载指示器。 我尝试使用Angular Http Interceptor,但指标样式永远不会更新。
我的app.component.html中有一个loading indicator
StoreManager::StoreManager() {
// Verify that the version of the library that we linked against is
// // compatible with the version of the headers we compiled against.
GOOGLE_PROTOBUF_VERIFY_VERSION;
// file = "data.db";
// // Read the existing data.
input = fstream(file, ios::in | ios::binary);
if (!input) {
input.close();
cout << file << ": File not found. Creating a new file." << endl;
fstream output(file, ios::out | ios::trunc | ios::binary);
if (!output)
cout << file << ": Failed to create a new file" << endl;
else{
appData.SerializeToOstream(&output);
output.close();
cout << file << ": New empty file created " << endl;
}
input = fstream(file, ios::in | ios::binary);
if (!input) {
cout << file << ": File not found. Failed to creating a new file." << endl;
}
}
if (!appData.ParseFromIstream(&input)) {
cerr << "Failed to parse in date storage." << endl;
}
}
AppData* StoreManager::getData() {
return &appData;
}
void StoreManager::save(){
// Write back to disk.
fstream output(file, ios::out | ios::trunc | ios::binary);
if (!appData.SerializeToOstream(&output)) {
cerr << "Failed to write in date storage." << endl;
}
output.close();
}
这是app.component.ts:
<div [style.display]="visibilityOfLoadingIndicator">
<mat-progress-bar mode="indeterminate" color="warn" ></mat-progress-bar>
</div>
这是HttpLoadingIndicatorService.ts:
export class AppComponent {
visibilityOfLoadingIndicator = 'none';
constructor(public loadingIndicatorService: LoadingIndicatorService) {
this.loadingIndicatorService.getLoadingIndicator()
.subscribe(visibility => {
this.visibilityOfLoadingIndicator = <string> visibility;
});
}
}
我的服务正在运行,例如,这是控制台输出:
@Injectable({
providedIn: 'root'
})
export class LoadingIndicatorService implements HttpInterceptor {
private display;
private loadingIndicator: EventEmitter<string>;
constructor() {
this.loadingIndicator = new EventEmitter<string>();
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const started = Date.now();
console.log('Request started');
this.display = 'block';
this.updateVisibility(this.display);
return next.handle(req)
.pipe(
finalize(
() => {
const elapsed = Date.now() - started;
const msg = `${req.method} "${req.urlWithParams}"
in ${elapsed} ms.`;
console.log(msg);
this.display = 'none';
this.updateVisibility(this.display);
}
)
)
;
}
updateVisibility(state: string) {
this.loadingIndicator.emit(state);
}
getLoadingIndicator() {
return this.loadingIndicator;
}
}
但是为什么指标样式没有更新?
我应该创建Observable吗?
答案 0 :(得分:0)
是的,您需要让组件订阅服务中的更改,以便它可以告诉Angular一切已更改。
constructor(public authenticationService: AuthenticationService,
public loadingIndicatorService: HttpLoadingIndicatorService,
changeDetector: ChangeDetectorRef) {
loadingIndicatorService.displayChangeObservable.subscribe(() =>
{
changeDetector.markForCheck();
});
}
displayLoadingIndicator() {
return this.loadingIndicatorService.display;
}
}
服务
@Injectable({
providedIn: 'root'
})
export class HttpLoadingIndicatorService implements HttpInterceptor {
private displayChangeSubject = new Subject<any>();
public displayChangeObservable = this.displayChangeSubject.asObservable();
display = 'none';
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const started = Date.now();
console.log('Request started');
this.display = 'block';
this.displayChangeSubject.next();
return next.handle(req)
.pipe(
finalize(
() => {
const elapsed = Date.now() - started;
const msg = `${req.method} "${req.urlWithParams}"
in ${elapsed} ms.`;
console.log(msg);
this.display = 'none';
this.displayChangeSubject.next();
}
)
)
;
}
}