Angular 6 主题订阅无效
Angular 6 Subject Subscribe is not working
我有一个 http interceptor,它会在请求开始和结束时发出 'string':
@Injectable({
providedIn: 'root'
})
export class LoadingIndicatorService implements HttpInterceptor {
private loadingIndicatorSource = new Subject<string>();
private loadingIndicator$ = this.loadingIndicatorSource.asObservable();
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.updateVisibility('block');
return next.handle(req)
.pipe(
finalize(
() => {
this.updateVisibility('none');
}
)
)
;
}
updateVisibility(state: string) {
this.loadingIndicatorSource.next(state);
}
getLoadingIndicator() {
return this.loadingIndicator$;
}
}
这是我注入服务的组件:
export class AppComponent {
display = 'none';
constructor(public authenticationService: AuthenticationService,
public loadingIndicatorService: LoadingIndicatorService) {
this.loadingIndicatorService.getLoadingIndicator().subscribe(visibility => {
console.log(visibility);
this.display = visibility;
});
}
}
实际上我正在尝试显示加载指示器:
<div [style.display]="display">
<mat-progress-bar mode="indeterminate" color="warn" ></mat-progress-bar>
</div>
我从官方 Angular 网站下载了 this 教程。
但是订阅方法永远不会执行。
为什么订阅方法不起作用?
我会做的是创建一个 SpinnerService 和一个 SpinnerInterceptor,而不是将它们合并在一起。
使微调器服务分配未完成请求的数量,并在未完成请求大于 0 时显示微调器。
@Injectable()
export class SpinnerService {
private requestAmount$ = new BehaviorSubject(0);
public showSpinner$ = this.requestAmount$.asObservable().pipe(map(r => r > 0));
requestStart() {
this.requestAmount$.next(this.requestAmount$.getValue() + 1);
}
requestEnd() {
this.requestAmount$.next(this.requestAmount$.getValue() - 1);
}
}
在您的 spinnerInterceptor 中,您可以注入 SpinnerService 并根据每个请求更新它。
@Injectable()
export class SpinnerInterceptor implements HttpInterceptor {
constructor(private spinnerService: SpinnerService) {}
intercept(req: HttpRequest<any>, next: HttpHandler) {
this.spinnerService.requestStart();
return next.handle(req).pipe(
finalize(() => {
this.spinnerService.requestEnd();
})
);
}
}
在您的应用程序组件中使用 ngOnInit
挂钩,不要使用违反样式指南的构造函数。
export class AppComponent implements OnInit{
display = 'none';
constructor(public authenticationService: AuthenticationService,
public spinnerService: SpinnerService) {}
ngOnInit(){
this.spinnerService.showSpinner$.subscribe(visibility => {
console.log(visibility);
this.display = visibility ? 'block': 'none';
});
}
}
分开更容易阅读和理解。
希望对您有所帮助!
我有一个 http interceptor,它会在请求开始和结束时发出 'string':
@Injectable({
providedIn: 'root'
})
export class LoadingIndicatorService implements HttpInterceptor {
private loadingIndicatorSource = new Subject<string>();
private loadingIndicator$ = this.loadingIndicatorSource.asObservable();
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.updateVisibility('block');
return next.handle(req)
.pipe(
finalize(
() => {
this.updateVisibility('none');
}
)
)
;
}
updateVisibility(state: string) {
this.loadingIndicatorSource.next(state);
}
getLoadingIndicator() {
return this.loadingIndicator$;
}
}
这是我注入服务的组件:
export class AppComponent {
display = 'none';
constructor(public authenticationService: AuthenticationService,
public loadingIndicatorService: LoadingIndicatorService) {
this.loadingIndicatorService.getLoadingIndicator().subscribe(visibility => {
console.log(visibility);
this.display = visibility;
});
}
}
实际上我正在尝试显示加载指示器:
<div [style.display]="display">
<mat-progress-bar mode="indeterminate" color="warn" ></mat-progress-bar>
</div>
我从官方 Angular 网站下载了 this 教程。
但是订阅方法永远不会执行。
为什么订阅方法不起作用?
我会做的是创建一个 SpinnerService 和一个 SpinnerInterceptor,而不是将它们合并在一起。
使微调器服务分配未完成请求的数量,并在未完成请求大于 0 时显示微调器。
@Injectable()
export class SpinnerService {
private requestAmount$ = new BehaviorSubject(0);
public showSpinner$ = this.requestAmount$.asObservable().pipe(map(r => r > 0));
requestStart() {
this.requestAmount$.next(this.requestAmount$.getValue() + 1);
}
requestEnd() {
this.requestAmount$.next(this.requestAmount$.getValue() - 1);
}
}
在您的 spinnerInterceptor 中,您可以注入 SpinnerService 并根据每个请求更新它。
@Injectable()
export class SpinnerInterceptor implements HttpInterceptor {
constructor(private spinnerService: SpinnerService) {}
intercept(req: HttpRequest<any>, next: HttpHandler) {
this.spinnerService.requestStart();
return next.handle(req).pipe(
finalize(() => {
this.spinnerService.requestEnd();
})
);
}
}
在您的应用程序组件中使用 ngOnInit
挂钩,不要使用违反样式指南的构造函数。
export class AppComponent implements OnInit{
display = 'none';
constructor(public authenticationService: AuthenticationService,
public spinnerService: SpinnerService) {}
ngOnInit(){
this.spinnerService.showSpinner$.subscribe(visibility => {
console.log(visibility);
this.display = visibility ? 'block': 'none';
});
}
}
分开更容易阅读和理解。
希望对您有所帮助!