angular - 输入 url 时 canActivate 不起作用
问题描述
基本上一切正常,直到由于某种原因输入 url 时,方法 canActivate 中的变量 this.estado 恰好未定义。
我认为这是因为构造函数没有在正确的时间获得 observable。
import { Component, Injectable, Inject, OnInit } from '@angular/core';
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
@Injectable()
export class AuthService implements CanActivate {
myAppUrl: string;
estado: any;
constructor(private router: Router, private http: HttpClient, @Inject('BASE_URL') private baseUrl: string) {
this.myAppUrl = baseUrl;
this.estadoSetUp(); /* If I put hear this.estado = true everything works fine */
}
public getJSON(): Observable<any> {
return this.http.get(this.myAppUrl + 'api/IsAuthenticated');
}
public estadoSetUp() {
this.getJSON().subscribe(data => {
this.estado = data.AmILoggin;
});
}
canActivate(): Observable<boolean> {
if (this.estado != true) {
this.router.navigate(['/']);
}
return this.estado;
}
}
感谢@sirdieter 解决了
我把解决方案留给将来遇到麻烦的人:
import { Component, Injectable, Inject, OnInit } from '@angular/core';
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { ReplaySubject } from 'rxjs/ReplaySubject'
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
import 'rxjs/add/operator/do';
@Injectable()
export class AuthService implements CanActivate {
myAppUrl: string;
private isAuthorized = new ReplaySubject<boolean>(1);
constructor(private router: Router, private http: HttpClient, @Inject('BASE_URL') private baseUrl: string) {
this.myAppUrl = baseUrl;
this.estadoSetUp();
}
public getJSON(): Observable<any> {
return this.http.get(this.myAppUrl + 'api/IsAuthenticated');
}
public estadoSetUp() {
this.getJSON().subscribe(data => {
this.isAuthorized.next(data.AmILoggin);
});
}
canActivate(): Observable<boolean> {
return this.isAuthorized.asObservable()
.do(auth => {
if (auth != true) {
this.router.navigate(['/']);
}
});
}
}
解决方案
请注意,您的 http 调用是异步的,
因此,当您直接打开一个 URL 时,会构造这个守卫(它会启动 http 调用),然后很快(毫秒)就会调用“canActivate”。结果,如果您的 http 调用不够快,则您的变量没有定义,因为 http 调用没有结果。
canActivate 返回一个布尔值的 Observable。因此,一种解决方案是将变量 estado 更改为可观察的
推荐阅读
- vb.net - 尽管处于尝试块中,但抛出异常停止应用程序
- sql-server - 优化 Google Scripts 调用 - 超时问题
- python - Microsoft Teams - 机器人主程序中的无限循环
- javascript - 将变量插入 PHP 标头位置 URL
- django - Django 模板 - 将日期时间格式转换为字符串
- android - ViewModel中查询不需要显示在Activity中的数据
- azure-cosmosdb - 在 Azure Cosmos DB 中,我是否需要将分区键添加到我的查询 where 子句中?
- r - 计算 R 中每列的 NA 总数
- angular - 在一次调用中处理两种不同类型的返回(文件(Blob)或 JSON)
- javascript - 查找一个 Div 中的第 N 个子元素在另一个 Div 中