[英]How to use an observable in angular 2 guards' canActivate()
我已經為我的angular2 rc5應用程序創建了一個身份驗證保護。
我也在使用redux商店。 在該商店中,我保留用戶的身份驗證狀態。
我了解到守衛可以返回可觀察到的或應許的( https://angular.io/docs/ts/latest/guide/router.html#!#guards )
我似乎無法找到一種讓守衛等待存儲/可觀察對象更新的方法,並且只有在該更新之后才返回守衛,因為存儲的默認值始終為false。
第一次嘗試:
@Injectable()
export class AuthGuard implements CanActivate {
@select(['user', 'authenticated']) authenticated$: Observable<boolean>;
constructor() {}
canActivate(): Promise<boolean> {
return new Promise((resolve, reject) => {
// updated after a while ->
this.authenticated$.subscribe((auth) => {
// will only reach here after the first update of the store
if (auth) { resolve(true); }
// it will always reject because the default value
// is always false and it takes time to update the store
reject(false);
});
});
}
}
第二次嘗試:
@Injectable()
export class AuthGuard implements CanActivate {
@select(['user', 'authenticated']) authenticated$: Observable<boolean>;
constructor() {}
canActivate(): Promise<boolean> {
return new Promise((resolve, reject) => {
// tried to convert it for single read since canActivate is called every time. So I actually don't want to subscribe here.
let auth = this.authenticated$.toPromise();
auth.then((authenticated) => {
if (authenticated) { resolve(true); }
reject(false);
});
auth.catch((err) => {
console.log(err);
});
}
}
當您訂閱一個可觀察對象時,您可以提供一個回調函數。 在下面的示例中,我將其稱為CompleteGet
。 CompleteGet()
僅在成功返回數據而不是錯誤的get時調用。 您可以在回調函數中放置任何所需的邏輯。
getCursenByDateTest(){
this.cursenService
.getCursenValueByDateTest("2016-7-30","2016-7-31")
.subscribe(p => {
this.cursens = p;
console.log(p)
console.log(this.cursens.length);
},
error => this.error = error,
() => this.CompleteGet());
}
completeGet() {
// the rest of your logic here - only executes on obtaining result.
}
我相信您也可以將.do()添加到可觀察的訂閱中以完成相同的操作。
您需要做的就是強迫可觀察對象進行更新:
canActivate(): Observable<boolean> {
return this.authenticated$.take(1);
}
編輯:canActivate等待可觀察的源完成,並且(很可能,我不知道幕后發生了什么), authenticated$
觀察的發出.next()
,而不是.complete()
來自文檔: http : //reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-take
.take(1)
方法首先獲取可觀察到的源發出的值,然后完成
Edit2:我只是看着您粘貼的代碼片段,而我是對的-可觀察到的store.select()
永遠不會完成,它總是發出.next
訂閱不返回Observable。 但是,您可以像這樣使用map運算符:
this.authenticated$.map(
authenticated => {
if(authenticated) {
return true;
}
return false;
}
).first() // or .take(1) to complete on the first event emit
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.