我为angular2 rc5应用程序创建了一个身份验证保护。
我也在使用redux商店。在那个商店中,我保留了用户的身份验证状态。
我读到警卫可以返回一个可观察或承诺(https://angular.io/docs/ts/latest/guide/router.html#!#guards)
我似乎无法找到一种方法让警卫等待商店/观察者更新并且只有 后更新才会返回警卫因为默认值商店总是假的。
首先尝试:
@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);
});
}
}
答案 0 :(得分:0)
订阅observable时,可以提供回调函数;在下面的示例中,我称之为CompleteGet
。 CompleteGet()
只会在成功获取时调用,返回数据而不是错误。您可以在回调函数中放置所需的逻辑。
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.
}
我相信你也可以在observable订阅中添加一个.do()来完成同样的事情。
答案 1 :(得分:0)
您需要做的就是强制observable更新:
canActivate(): Observable<boolean> {
return this.authenticated$.take(1);
}
编辑:
canActivate等待源observable完成,并且(很可能,我不知道幕后发生了什么),authenticated$
observable发出.next()
,而不是.complete()
来自文档:http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-take
.take(1)
方法获取源observable发出的第一个值,然后完成
EDIT2:
我只看了你粘贴的片段,我是对的 - store.select()
观察者永远不会完成,它总是会发出.next
答案 2 :(得分:0)
订阅不会返回Observable。 但是,您可以像这样使用地图运算符:
this.authenticated$.map(
authenticated => {
if(authenticated) {
return true;
}
return false;
}
).first() // or .take(1) to complete on the first event emit