Angular 组合RxJS,可在角度方向观察

Angular 组合RxJS,可在角度方向观察,angular,firebase,rxjs,Angular,Firebase,Rxjs,问题:如果firebase auth没有用户登录,我需要路由到登录页面;如果firebase auth没有用户登录,我需要路由到备用页面 为了实现这一点,它将调用构造函数服务中的函数 private isLoginRequired() { // Firebase auth service observable let authSub = this.afAuth.authState; // Current route service observable let routeSub = this.

问题:如果firebase auth没有用户登录,我需要路由到登录页面;如果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
  }
});
请告诉我一条更好的出路。提前谢谢

依赖关系:“rxjs”:“~6.3.3”


我不是100%确定你在做什么,但听起来像是
combinelateest
可能有用

// 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
是一个很好的例子,所以当您订阅时,它会给您提供最新的结果,我想Firebase身份验证服务也会如此,但您必须对其进行测试

这里面可能有语法错误,只需直接键入,但这是您的基本
combineTest

  • 关于数组参数的文章
  • 文件

我不是100%确定你在做什么,但听起来好像
combinelateest
可能有用

// 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
是一个很好的例子,所以当您订阅时,它会给您提供最新的结果,我想Firebase身份验证服务也会如此,但您必须对其进行测试

这里面可能有语法错误,只需直接键入,但这是您的基本
combineTest

  • 关于数组参数的文章
  • 文件

我会使用路线守卫来完成您所描述的工作:

这是来自Jeff Delaney的AngularFirebase网站的稍加修改的代码片段,请参见:

您可以像我在这里所做的那样,在guard中导入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']);
            }
        })
    }
}

我将使用路线守卫执行您所描述的操作:

这是来自Jeff Delaney的AngularFirebase网站的稍加修改的代码片段,请参见:

您可以像我在这里所做的那样,在guard中导入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']);
            }
        })
    }
}

最后,我在@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"]);
    }
  }
);
}
private isLoginRequired():void{
让authSub:Observable=this.afAuth.authState;
让routeSub:Observable=this.router.events;
组合测试(authSub、routeSub)。订阅(
([authSubSnap,routeSubSnap]):void=>{
让islogin:boolean=!!authSubSnap;
让当前url:string=routeSubSnap.url;
如果(!islogin){
this.router.navigate([this.loginPageURL]);
}else if(当前_url===this.loginPageURL&&islogin){
this.router.navigate([“工具/事件管理/事件]);
}
}
);
}

最后,我在help@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"]);
    }
  }
);
}
private isLoginRequired():void{
让authSub:Observable=this.afAuth.authState;
让routeSub:Observable=this.router.events;
组合测试(authSub、routeSub)。订阅(
([authSubSnap,routeSubSnap]):void=>{
让islogin:boolean=!!authSubSnap;
让当前url:string=routeSubSnap.url;
如果(!islogin){
this.router.navigate([this.loginPageURL]);
}else if(当前_url===this.loginPageURL&&islogin){
this.router.navigate([“工具/事件管理/事件]);
}
}
);
}

您不应该订阅内部obs,而应该订阅外部obs。@MikeOne我尝试过交换它们,但没有多大帮助。您有没有研究过路由器防护装置?它们可以在用户登录页面之前处理身份验证逻辑。@sketchthat,如果用户已经在页面上,并且从第二个选项卡触发锁定该页面的事件(如注销)会发生什么情况?下面是一篇文章,展示了以角度合并观察对象的可视化方法。值得一看。你不应该订阅你的内部obs,而应该订阅你的外部obs。@MikeOne我尝试过交换它们,但没有多大帮助。你有没有在Angular研究过路由器防护?它们可以在用户登录页面之前处理身份验证逻辑。@sketchthat,如果用户已经在页面上,并且从第二个选项卡触发锁定该页面的事件(如注销)会发生什么情况?下面是一篇文章,展示了以角度合并观察对象的可视化方法。值得一看。请注意,在每个可观察对象发出至少一个值之前,CombineTest不会发出初始值。activatedRoute.url是BehaviorSubject的可观察对象,因此它会“一次”向您提供最新结果,因此上述代码没有进入subscribe()。这对我来说是一个惊喜,所以我将代码更改为CombineTest(This.afAuth.authState,This.router.events).subscribe(),并且工作得非常好。非常感谢。随着router.events触发数十个事件,这可能会被多次命中。您可以添加一个
管道(filter())
来只处理您感兴趣的事件,例如
filter(event=>event instanceof NavigationEnd)
。您的参数将不同,但相同的想法我知道CombineTest不会发出初始值,直到每个可观察对象发出至少一个值。activatedRoute.url是BehaviorSubject的可观察对象,因此它会“一次”给您最新的结果,因此上述代码没有进入subscribe()。这对我来说是一个惊喜,所以我将代码更改为CombineTest(This.afAuth.authState,This.router.events).subscribe(),并且工作得非常好。非常感谢。这可能会被多次击中