[英]How to combine query parameter observable and form observable using Angular and RXJS
[英]Combine RxJS Observable in Angular
问题 :如果firebase-auth没有用户登录,我需要路由到登录页面,如果有用户登录,我需要路由到备用页面。
为此,它将在构造函数服务中调用一个函数。
private isLoginRequired() {
// Firebase auth service observable
let authSub = this.afAuth.authState;
// Current route service observable
let routeSub = this.activatedRoute.url;
//Alternate App Page
//this.router.navigate(["tool/event-management/events"]);
//Login Page
//this.router.navigate(["tool/event-management/login"]);
}
现在,我需要以一种这样的方式组合这些可观察对象: 如果其中任何一个的值发生变化,我都可以通过单次订阅收集两个可观察对象的当前值。
something.subscribe(observableSnapshots => {
let snapshot_auth = observableSnapshots[0];
let snapshot_route = observableSnapshots[1];
if(condition<snapshot_route, snapshot_auth>){
// do anything positive
}
else{
// do anything negative
}
});
我知道可以通过嵌套订阅来实现,但这肯定不是一种有效的方式。
我也尝试过mergeMap但无法达到要求,这是代码段(无效)
routeSub
.pipe(mergeMap(event1 => authSub.pipe(map(event2 => "test"))))
.subscribe(result => {
console.log(result);
});
请告诉我更好的出路。 提前致谢。
依赖项 :“ rxjs”:“〜6.3.3”
我会使用路由守卫来做您正在描述的事情:
这是Jeff Delaney的AngularFirebase网站的经过稍微修改的代码段,请参阅: https ://angularfirebase.com/lessons/google-user-auth-with-firestore-custom-data/:
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { AngularFireAuth } from '@angular/fire/auth';
import { Observable } from 'rxjs';
import { tap, map, take } from 'rxjs/operators';
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private auth: AngularFireAuth, private router: Router)
{}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> {
return this.auth.authState.pipe()
take(1),
map(user => !!user),
tap(loggedIn => {
if (!loggedIn) {
console.log('access denied')
this.router.navigate(['/login']);
}
})
)
}
}
以下是将防护添加到路由器的方法:
const routes: Routes = [
{ path: '**', component: SomeComponent, canActivate: [AuthGuard]},
]
您可以像在此所做的那样在警卫中导入可观察到的Firebase auth
,但是,最好在自己的服务imo中添加它。 检查指向AngularFirebase的链接以查看执行此操作的服务的代码。
如果要在注销后将用户拒之门外,请在组件中尝试以下代码:
export class SomeComponent implements OnInit {
constructor(private auth: AngularFireAuth, private router: Router)
{
ngOnInit(): void {
this.auth.authState.subscribe((authObj) => {
if(authObj === null){
this.router.navigate(['/login']);
}
})
}
}
我不是100%知道您在做什么,但这听起来好像combineLatest
可能combineLatest
// Firebase auth service observable
let authSub = this.afAuth.authState;
// Current route service observable
let routeSub = this.activatedRoute.url;
const sub = combineLatest(authSub, routeSub)
.pipe(
tap(([authResult, routeResult]) => {
// the above uses array param destructuring, so we have two variables
if(authResult === something and routeResult === something){
//Do Something
}
else {
// do something else
}
})
)
.subscribe();
activatedRoute.url
是BehaviorSubject
一个可观察对象,因此在您订阅时它将为您提供最新结果,并且我认为Firebase Auth服务也是如此,但是您必须对其进行测试
可能会有语法错误,只需直接输入即可,但这是您的基本combineLatest
最后,我得到了@Drenai帮助的代码片段。
private isLoginRequired():void {
let authSub: Observable<firebase.User> = this.afAuth.authState;
let routeSub: Observable<any> = this.router.events;
combineLatest(authSub, routeSub).subscribe(
([authSubSnap, routeSubSnap]):void => {
let islogin: boolean = !!authSubSnap;
let current_url: string = routeSubSnap.url;
if (!islogin) {
this.router.navigate([this.loginPageURL]);
} else if (current_url === this.loginPageURL && islogin) {
this.router.navigate(["tool/event-management/events"]);
}
}
);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.