Angular 4:无法订阅从CanActivate AccessGuard
问题描述:
观察值我遵循了很多教程,并尝试了许多组合,但无法使这项工作。Angular 4:无法订阅从CanActivate AccessGuard
我需要在用户登录时让路由可用。如果他不是我需要将他重定向到主页(this._popupService.setCallbackRoute(route.url.join('/')))
并显示一个弹出窗口(this._popupService.showPopUp())
,让他登录或注册。
我无法从authService获取syncronized值。这是我的代码:
app.module.ts
imports: [
BrowserModule,
FormsModule,
HttpModule,
RouterModule.forRoot(
{path: '', component: HomepageComponent},
{
path: 'protectedRoute',
component: SubmitComponent,
data: {requiresLogin: true},
canActivate: [AccessGuard]
}
),
...
]
auth.service.ts
@Injectable()
export class AuthService {
private loggedIn: Subject<boolean> = new Subject<boolean>();
get isLoggedIn() {
return this.loggedIn.asObservable();
}
login(user: IUser) {
return this._http.get('assets/api/responseSuccess.json?email=' + user.email + '&password=' + user.password)
.map((responseLogin => {
const jsonResponse = responseLogin.json();
if (jsonResponse.response === 'success') {
const userResponse: IUser = jsonResponse.user;
this._sessionService.setUserSession(userResponse);
this.loggedIn.next(true);
return true;
} else {
this._customFlashMessages.show('Got error login, please check your credentials and try again!');
return false;
}
}));
}
}
accessGuard.service.ts
import {Injectable} from '@angular/core';
import {ActivatedRouteSnapshot, CanActivate, Router} from '@angular/router';
import {Observable} from 'rxjs/Observable';
import {AuthService} from './auth.service';
import {PopUpService} from './popup.service';
@Injectable()
export class AccessGuard implements CanActivate {
loggedIn$: Observable<boolean>;
constructor(private authService: AuthService, private _popupService: PopUpService, private router: Router) {
this.loggedIn$ = this.authService.isLoggedIn;
}
canActivate(route: ActivatedRouteSnapshot): Observable<boolean> | Promise<boolean> | boolean {
const requiresLogin = route.data.requiresLogin || false;
if (requiresLogin) {
this.authService.isLoggedIn.subscribe(// even tried with .map()
result => {
console.log(result); // Logs a promise object
if (!result) {
console.log("protected route"); // Never reached
// If not logged in shop popup and stay on that page
this._popupService.showPopUp();
this._popupService.setCallbackRoute(route.url.join('/'));
return false;
}
console.log('logged in'); // Never reached
return true;
});
}
return true;
}
}
我尝试了几件事情。我的代码工作,如果我直接检查sessionStorage('用户'),但不能使用observable。
任何帮助表示赞赏。
谢谢!
答
这是正确答案,问题出在订阅方法里面的逻辑里。
这里是正确的accesGuard.service.ts
@Injectable()
export class AccessGuard implements CanActivate {
constructor(private authService: AuthService, private _popupService: PopUpService, private router: Router) {
}
canActivate(route: ActivatedRouteSnapshot): Observable<boolean> | Promise<boolean> | boolean {
const requiresLogin = route.data.requiresLogin || false;
if (requiresLogin) {
this.authService.isLoggedIn.subscribe(
result => {
if (!result) {
// If not logged in shop popup and stay on that page
this._popupService.showPopUp();
this._popupService.setCallbackRoute(route.url.join('/'));
this.router.navigate(['/']);
return false;
}
return true;
});
return true;
}else{
return true;
}
}
}
答
你需要返回一个observable。
canActivate(route: ActivatedRouteSnapshot): Observable<boolean> | Promise<boolean> | boolean {
const requiresLogin = route.data.requiresLogin || false;
if (requiresLogin) {
return this.authService.isLoggedIn;
}
return Observable.of(false);
}
从你的解释,弹出必须是不是后卫,但在网页组件,在其内部可以实现'ngOnInit()'检查,如果用户'isSignedIn',如果不是,用登录表单触发弹出窗口。 Guard在返回false之前只能重定向到主页。 – Vadim