Angular 订阅代码适用于直接页面加载但不适用于通过路由
Angular subscribe code works on direct page load but not through route
我遇到了 angular 的问题。
我有一个 authService,我正在通过我的所有组件使用它,我正在使用一个主题,如果我需要检查用户是否已登录,我可以在我的组件中订阅它,我面临的问题是如果我直接加载将使用它的页面,这工作正常,但不是当我通过路线时。
所以我加载 http://localhost:4200/testing 这是这个组件
import { Component, OnInit } from '@angular/core';
import {AuthenticationService} from "../../services/authentication.service";
@Component({
selector: 'app-testing',
templateUrl: './testing.component.html',
styleUrls: ['./testing.component.css']
})
export class TestingComponent implements OnInit {
loggedIn: boolean = false;
constructor(private authService: AuthenticationService) { }
ngOnInit() {
this.authService.getLoginStatus().subscribe(loginStatus => this.loggedIn = loginStatus);
}
}
这段代码所做的就是订阅 authService Subject,如下所示
import {Injectable} from '@angular/core';
import {HttpClient} from "@angular/common/http";
import {environment} from "../../environments/environment";
import 'rxjs/add/operator/map'
import {UserService} from "./user.service";
import {Subject} from "rxjs/Subject";
import {Subscription} from "rxjs/Subscription";
@Injectable()
export class AuthenticationService {
private isLoggedIn = new Subject<boolean>();
private apiUrl = environment.apiUrl + 'login/';
private deleteSubscribe: Subscription;
constructor(private http: HttpClient,
private userService: UserService) {
this.isLoggedIn.next(false);
}
login(username: string, password: string) {
return this.http.post<any>(this.apiUrl + '?' + environment.apiDebug, {
username: username,
password: password
}).map(user => {
// Login success if there is a JWT token in the
if (user.loginSucess && user.token) {
// Store the user details and JWT token in the local storage to keep the user logged in between page refreshes
localStorage.setItem('currentUser', user.token);
// Grab the user data then set logged in equal to true
this.userService.getAccountDetails().subscribe(userData => {
this.isLoggedIn.next(true);
});
}
return user;
});
}
checkLoginStatus() {
if (localStorage.getItem('currentUser')) {
return this.http.get<any>(this.apiUrl + 'check_login')
.map(loginStatusReturn => {
if (loginStatusReturn.isLoggedIn === true) {
this.isLoggedIn.next(true);
this.userService.getAccountDetails().subscribe();
return true;
} else {
// Delete the local stored cookie, It was invalid
localStorage.removeItem('currentUser');
this.isLoggedIn.next(false);
this.userService.clearUserInfo();
return false;
}
})
}
}
logout() {
// Remove user from the local storage
this.deleteSubscribe = this.http.delete(this.apiUrl + 'logout?').subscribe();
localStorage.removeItem('currentUser');
this.userService.clearUserInfo();
this.isLoggedIn.next(false);
this.deleteSubscribe.unsubscribe();
}
getLoginStatus() {
return this.isLoggedIn.asObservable();
}
}
当我直接加载页面时,我看到测试组件中的 loginStatus 设置为 true,一切正常,如果我然后单击另一个页面,然后单击路由器 link 返回测试页面订阅块中的代码永远不会 运行 并且登录状态保持在 false
我在供应商
下的 app.module.ts 中导入了服务
我正处于用这个头撞桌子的阶段
任何帮助将不胜感激
干杯
您的主题 (isLoggedIn
) 可能需要 ReplaySubject
。 ReplaySubject
将 re-emit 所有新订阅者的最后一个值。现在,当您的第二个组件订阅时,它不会收到事件。
您的应用模块中似乎提供了此服务,这意味着它只会被初始化一次(当应用首次加载时)。因此,您的构造函数中的 this.isLoggedIn.next(false)
只会触发一次——可能在您的新组件初始化之前。
我遇到了 angular 的问题。
我有一个 authService,我正在通过我的所有组件使用它,我正在使用一个主题,如果我需要检查用户是否已登录,我可以在我的组件中订阅它,我面临的问题是如果我直接加载将使用它的页面,这工作正常,但不是当我通过路线时。
所以我加载 http://localhost:4200/testing 这是这个组件
import { Component, OnInit } from '@angular/core';
import {AuthenticationService} from "../../services/authentication.service";
@Component({
selector: 'app-testing',
templateUrl: './testing.component.html',
styleUrls: ['./testing.component.css']
})
export class TestingComponent implements OnInit {
loggedIn: boolean = false;
constructor(private authService: AuthenticationService) { }
ngOnInit() {
this.authService.getLoginStatus().subscribe(loginStatus => this.loggedIn = loginStatus);
}
}
这段代码所做的就是订阅 authService Subject,如下所示
import {Injectable} from '@angular/core';
import {HttpClient} from "@angular/common/http";
import {environment} from "../../environments/environment";
import 'rxjs/add/operator/map'
import {UserService} from "./user.service";
import {Subject} from "rxjs/Subject";
import {Subscription} from "rxjs/Subscription";
@Injectable()
export class AuthenticationService {
private isLoggedIn = new Subject<boolean>();
private apiUrl = environment.apiUrl + 'login/';
private deleteSubscribe: Subscription;
constructor(private http: HttpClient,
private userService: UserService) {
this.isLoggedIn.next(false);
}
login(username: string, password: string) {
return this.http.post<any>(this.apiUrl + '?' + environment.apiDebug, {
username: username,
password: password
}).map(user => {
// Login success if there is a JWT token in the
if (user.loginSucess && user.token) {
// Store the user details and JWT token in the local storage to keep the user logged in between page refreshes
localStorage.setItem('currentUser', user.token);
// Grab the user data then set logged in equal to true
this.userService.getAccountDetails().subscribe(userData => {
this.isLoggedIn.next(true);
});
}
return user;
});
}
checkLoginStatus() {
if (localStorage.getItem('currentUser')) {
return this.http.get<any>(this.apiUrl + 'check_login')
.map(loginStatusReturn => {
if (loginStatusReturn.isLoggedIn === true) {
this.isLoggedIn.next(true);
this.userService.getAccountDetails().subscribe();
return true;
} else {
// Delete the local stored cookie, It was invalid
localStorage.removeItem('currentUser');
this.isLoggedIn.next(false);
this.userService.clearUserInfo();
return false;
}
})
}
}
logout() {
// Remove user from the local storage
this.deleteSubscribe = this.http.delete(this.apiUrl + 'logout?').subscribe();
localStorage.removeItem('currentUser');
this.userService.clearUserInfo();
this.isLoggedIn.next(false);
this.deleteSubscribe.unsubscribe();
}
getLoginStatus() {
return this.isLoggedIn.asObservable();
}
}
当我直接加载页面时,我看到测试组件中的 loginStatus 设置为 true,一切正常,如果我然后单击另一个页面,然后单击路由器 link 返回测试页面订阅块中的代码永远不会 运行 并且登录状态保持在 false
我在供应商
下的 app.module.ts 中导入了服务我正处于用这个头撞桌子的阶段
任何帮助将不胜感激
干杯
您的主题 (isLoggedIn
) 可能需要 ReplaySubject
。 ReplaySubject
将 re-emit 所有新订阅者的最后一个值。现在,当您的第二个组件订阅时,它不会收到事件。
您的应用模块中似乎提供了此服务,这意味着它只会被初始化一次(当应用首次加载时)。因此,您的构造函数中的 this.isLoggedIn.next(false)
只会触发一次——可能在您的新组件初始化之前。