我有一个导航栏菜单组件,该组件具有取决于用户是否已登录的可选链接。在当前设置中,导航栏在初始化时检查登录状态(通过LoginService)。这是 NavMenuComponent.ts :
export class NavMenuComponent implements OnInit {
isExpanded = false;
isNavbarCollapsed = true;
isLoggedIn: boolean;
subscription: Subscription;
constructor(private jwtHelper: JwtHelper, private loginService: LoginService) {
this.subscription = loginService.checkLoginStatus.subscribe(
isLoggedIn => {
this.isLoggedIn = isLoggedIn
});
}
ngOnInit() {
//this.checkLoginStatus();
this.isLoggedIn = this.loginService.checkLoginStatus();
}
collapse() {
this.isExpanded = false;
}
toggle() {
this.isExpanded = !this.isExpanded;
}
}
我希望导航栏菜单组件在用户登录或注销时做出反应。这意味着在导航服务所订阅的LoginService或LoginComponent中以我的身份发布事件。您可以看到我试图在导航栏菜单中写一个订阅,但是没用!
我应该如何使它工作?
编辑:这是loginService:
export class LoginService {
//isLoggedIn: boolean;
constructor(private jwtHelper: JwtHelper) { }
//checkLoginStatus(): Observable<boolean> {
checkLoginStatus(): boolean {
var token = localStorage.getItem("jwt");
if (token && !this.jwtHelper.isTokenExpired(token)){
//console.log(this.jwtHelper.decodeToken(token));
alert("user is logged in");
//this.isLoggedIn = true;
return true;
}
else {
//this.isLoggedIn = false;
alert("user is NOT logged in");
return false;
}
}
}
答案 0 :(得分:1)
假设loginService.checkLoginStatus
是一个Observable
,一旦用户执行登录或登录,它将在boolean
或true
中推送新的false
值注销,您可以简单地使用它。
实际上,您已经在使用它。因此,只要用户的登录状态发生变化,组件上的isLoggedIn
属性就会更新。因此,您应该可以直接在模板中使用它。
而且,既然是这种情况,就不需要您在ngOnInit
中拥有的代码。实际上,您可以将constructor
代码移至ngOnInit
并稍微重构代码。像这样:
export class NavMenuComponent implements OnInit {
isExpanded = false;
isNavbarCollapsed = true;
isLoggedIn: boolean;
subscription: Subscription;
constructor(
private jwtHelper: JwtHelper,
private loginService: LoginService
) {}
ngOnInit() {
this.subscription = loginService.checkLoginStatus
.subscribe(isLoggedIn => this.isLoggedIn = isLoggedIn);
}
...
}
我认为您应该在private
中创建一个BehaviorSubject
LoginService
,然后将其公开发布asObservable
。现在,一旦用户登录,只需在此专用.next(true)
上呼叫BehaviorSubject
,然后在用户注销时,呼叫.next(true)
。
import { BehaviorSubject, Observable } from 'rxjs';
export class LoginService {
private isLoggedIn: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
isLoggedIn$: Observable<boolean> = this.isLoggedIn.asObservable();
constructor(private jwtHelper: JwtHelper) {}
...
// When Login
this.isLoggedIn.next(true)
...
// When Logout
this.isLoggedIn.next(false)
/* checkLoginStatus(): boolean {
var token = localStorage.getItem("jwt");
(token && !this.jwtHelper.isTokenExpired(token)) ? this.isLoggedIn.next(true): this.isLoggedIn.next(false);
} */
}
然后可以在组件中以通常的方式subscribe
到public
Observable
。
类似这样的东西:
export class NavMenuComponent implements OnInit {
isExpanded = false;
isNavbarCollapsed = true;
isLoggedIn: boolean;
subscription: Subscription;
constructor(
private jwtHelper: JwtHelper,
private loginService: LoginService
) {}
ngOnInit() {
this.subscription = this.loginService.isLoggedIn$
.subscribe(isLoggedIn => this.isLoggedIn = isLoggedIn);
}
...
}
答案 1 :(得分:1)
在LoginService下面,由于我添加了loggingStatus eventemitter对象,它可能会对您有所帮助。因此,当用户基于该特定值登录或注销时,我们正在发射,而在Nav组件中将获得相同的值。
export class LoginService {
//isLoggedIn: boolean;
loggedStatus = new EventEmitter<boolean>();
constructor(private jwtHelper: JwtHelper) { }
//checkLoginStatus(): Observable<boolean> {
checkLoginStatus(): boolean {
var token = localStorage.getItem("jwt");
if (token && !this.jwtHelper.isTokenExpired(token)){
//console.log(this.jwtHelper.decodeToken(token));
alert("user is logged in");
//this.isLoggedIn = true;
this.loggedStatus.emit(true);
return true;
}
else {
//this.isLoggedIn = false;
alert("user is NOT logged in");
this.loggedStatus.emit(false);
return false;
}
}
}
导航组件更改
下面的代码可以在ngOnInit方法中实现。
this.loginService.loggedStatus.subscribe(
isLoggedIn => {
this.isLoggedIn = isLoggedIn
});