[英]Angular - How to make canActivate to await for promise response?
如果用户已登录,我会尝试签入 CanActivate gurad。
如果是,那么我将他导航到某个页面。
如果没有,那么我将他导航到登录页面。
我使用 promise。
我有一个名为LoginService的服务:
export class LoginService {
urlcheck = 'http://localhost:80/isconnected.php';
resultCheck;
constructor(private http: HttpClient, private router: Router)
{
}
async checkLogin()
{
const x = await this.updateConnectedState();
return x;
}
updateConnectedState()
{
//formData here...
return this.http.post(this.urlcheck, formData).toPromise()
.then(
(response) =>
{
this.resultCheck = response;
console.log(response);
return this.resultCheck.state; //state is true/false
},
(error) =>
{
console.log(error);
return false;
}
);
}
}
canActivate Gurad:
export class BackHomeGuardService implements CanActivate
{
constructor(private logService: LoginService, private router: Router)
{
}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean>|boolean
{
const result = this.logService.checkLogin();
console.log( result);
if (result)
{
console.log('true');
// navigate to hom page
return true;
}
else
{
console.log('false');
// navigate to login page
return false;
}
}
}
守卫可以激活 function 总是返回 true。
我检查了控制台,promise 结果是:
__zone_symbol__state: null
__zone_symbol__value: []
我想让 canActive 在它做某事之前等待结果。
如果我的后端(php 代码文件)需要 30 秒才能完成怎么办?
我需要一个解决方案。 谢谢。
根据CanActivate
的类型:
export declare interface CanActivate {
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree;
}
方法canActivate
可以返回 Observable,Promise 或 boolean。
您可以简单地返回您的checkLogin()
调用,例如:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean>|boolean {
return this.logService.checkLogin();
}
一切都会奏效。
更新
从评论中回答问题“我如何处理我的 canActivate 中返回的 boolean”
CanActivate 的想法是由于某种条件限制对某些路由的访问。 您可以通过链接 Promise 或 Observable 来执行一些副作用(但我不确定它们将如何显示,除非它是 console.log):
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean>|boolean {
return this.logService
.checkLogin()
.then(canLogin => {
console.log('Can user login:', canLogin);
// perform you side effects here
})
}
如果查看 canActivate 方法的返回类型:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree
}
它可以返回一个简单的 boolean 或 Promise 或 Observable。 另外,我认为您不需要在 LoginService 中将 Observable 转换为 Promise。
canActivate 可以与 observable 一起使用,因此您可以 map 查询结果以这种方式返回 observable
import { of, Observable } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
export class LoginService {
urlcheck = 'http://localhost:80/isconnected.php';
resultCheck;
constructor(private http: HttpClient, private router: Router) {
}
checkLogin(): Observable<boolean> {
//formData here...
return this.http.post(this.urlcheck, formData).pipe(
map(
(response) => {
this.resultCheck = response;
console.log(response);
return this.resultCheck.state; //state is true/false
}),
catchError(error => {
console.log(error);
return of(false);
})
);
}
}
export class BackHomeGuardService implements CanActivate
{
constructor(private logService: LoginService, private router: Router)
{
}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean>
{
return this.logService.checkLogin();
}
}
canActivate
可以具有以下返回类型: boolean
、 Promise<boolean>
或Observable<boolean>
。
由于您已经有checkLogin()
返回一个Promise
,它将解析为true/false
。 让我们坚持使用Promise
或Observable
。 正如其他人已经回答的那样,您绝对可以返回this.logService.checkLogin()
canActivate(): Promise<boolean> {
return this.logService.checkLogin();
}
现在,我看到您还想根据checkLogin()
值导航到其他地方。 我建议将Promise
转换为Observable
,以便您可以利用tap
运算符。 你可以这样做:
return fromPromise(this.logService.checkLogin()).pipe(
tap(isLogin => {
if (!isLogin) {
// not login. navigate to login page
}
})
)
我们真的不想在true
的某个地方导航,因为当它为 true 时,Guard 会将用户导航到被保护的路线。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.