我刚刚开始在现有的应用程序中集成角度通用性,我注意到有一段时间,页面呈现了错误的布局,当页面完全加载时一切看起来都很好。
这是一个示例:
我在页面加载时得到的登录状态如下:
this.authService.isLoggedIn.subscribe(res => {
this.isLoggedIn = res;
});
然后根据结果(是或否)设置不同的布局:
<div *ngIf="isLoggedIn" class="user-logged">
// user logged in
</div>
<div *ngIf="!isLoggedIn" class="user-logged">
// user not logged in
</div>
但是当服务返回true(这意味着用户已登录)时,有一秒钟,我可以看到未登录状态,然后页面就会加载,并且一切正常。 所有BreakpointObserver检查也会发生这种情况。
更新1: 这是我尝试过的: 我创建了一个AppConfigService:
@Injectable()
export class AppConfigService {
private isLoggedStatus: boolean;
constructor(private authService: AuthService) { }
public isLoggedIn(): boolean {
return this.isLoggedStatus;
}
load() {
return new Promise((resolve, reject) => {
this.authService.isLoggedIn.subscribe(loggedInStatus => {
this.isLoggedStatus = loggedInStatus;
resolve(true);
});
});
}
}
在我的AuthService中:
private isLoginSubject = new BehaviorSubject<boolean>(this.isAuthenticated);
get isLoggedIn(): Observable<boolean> {
return this.isLoginSubject.asObservable();
}
get isAuthenticated(): boolean {
const token = this.getToken();
if (token) {
if (jwtHelper.isTokenExpired(token)) {
return false;
} else {
return true;
}
} else {
return false;
}
}
在我的app.module.ts
export function appConfigFactory(provider: AppConfigService) {
return () => provider.load();
}
providers: [
AppConfigService,
{
provide: APP_INITIALIZER,
useFactory: appConfigFactory,
deps: [AppConfigService],
multi: true
}
]
我认为问题出在服务器端使用本地存储,但是如果那是问题,我该如何检查用户是否已登录?
答案 0 :(得分:1)
发生这种情况是因为,当您的应用首次评估isLoggedIn
时,它为假(或未定义,取决于您如何定义它)。
然后,当订阅事件返回数据时,isLoggedIn
的值将更改,因此,由于*ngIf
的情况,您的html也将更改。
如果您想在应用渲染之前加载isLoggedIn
数据,则可以使用APP_INITIALIZER
。
这篇文章解释了如何使用它:https://www.cidean.com/blog/2019/initialize-data-before-angular-app-starts/
这个人年龄较大,但也很不错:https://devblog.dymel.pl/2017/10/17/angular-preload/
在您的AppConfigService
中,isLoggedStatus
应该是可观察的,否则在Promise解决之前,它将是未定义的(并且评估为false)。
您应该等待,直到承诺结束,再渲染您的组件。
示例步骤:
isLoggedStatus
= 真 LocalStorage
中)isLoggedIn
为真)isLoggedStatus
= 错误 isLoggedIn
为假)答案 1 :(得分:1)
发生这种情况是因为您使用了localStorage
。应用的服务器端版本无法访问本地存储(就像它无法访问任何浏览器对象上的window
,navigator
)一样,因此它认为用户未连接。
在使用角度通用和身份验证时,可以使用服务器可以访问的cookie。
有一些可用的库,但是从我看来,它们还没有完全可以在角度9中使用:
在此github issue中解决角度9。
不适用于角度通用github issue