我有以下方法:
isLoggedIn() : Observable<boolean>{
return this.isLoginSubject.asObservable().shareReplay(1).do(x=>console.log('called'));
}
在几个组件中,我有以下代码:
isLoggedIn: Observable<boolean>;
this.isLoggedIn = this._authService.isLoggedIn();
<header id="toolbar" *ngIf="isLoggedIn | async as isLoggedIn">
<app-toolbar></app-toolbar>
</header>
我注意到,当我登录时,'called'
被打印4次到控制台。我以为shareReplay
只会导致一次订阅?
服务:
export class AuthService {
isLoginSubject = new BehaviorSubject<boolean>(this.tokenNotExpired());
private sharedLogin$ = this.isLoginSubject
.shareReplay(1)
.do(x => console.log('called'));
constructor(private _httpClient: HttpClient) { }
authenticate(username, password) {
const user = {username, password};
const headers = new HttpHeaders();
headers.set('Content-Type', 'application/json');
return this._httpClient.post<any>(environment.api_url + '/auth', user, {headers: headers}).do(x=>{
this.isLoginSubject.next(true);
});
}
组件(ts):
ngOnInit() {
this.isLoggedIn = this._authService.isLoggedIn();
}
组件(HTML):
<div [class]="bodyClasses">
<aside id="sidebar" [ngClass]="{ 'active' : mobileNav }" (click)="mobileNav = !mobileNav" *ngIf="isLoggedIn | async as isLoggedIn">
<app-sidebar></app-sidebar>
</aside>
<main id="main" class="wrapper">
<header id="toolbar" *ngIf="isLoggedIn | async as isLoggedIn">
<app-toolbar></app-toolbar>
</header>
<div id="content">
<router-outlet></router-outlet>
</div>
</main>
</div>
我删除...| async
并在控制台中只注意到一个called
,但是当我退出时,它不会触发更改。注销时应隐藏的组件仍然显示:我在注销时执行以下操作:
logout() {
this.isLoginSubject.next(false);
}
答案 0 :(得分:4)
问题在于您多次调用this._authService.isLoggedIn()
方法多次创建链this.isLoginSubject.asObservable().shareReplay(1)...
(对于此方法的每次调用,它都会创建一个新链),所以如果您看到{{ 1}}打印4次,因为你订阅了4个不同的链。
所以你可以把链放到一个对象属性中,然后从'called'
方法返回它:
isLoggedIn()
或者您可以公开private sharedLogin$ = this.isLoginSubject
.shareReplay(1)
.do(x => console.log('called'));
isLoggedIn(): Observable<boolean> {
return this.sharedLogin;
}
并直接订阅它。