[英]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.