Angular 在可观察订阅方法中包含逻辑可以吗?

Angular 在可观察订阅方法中包含逻辑可以吗?,angular,rxjs,observable,apollo-client,Angular,Rxjs,Observable,Apollo Client,我在看@john_lindquist关于RxJS的书呆子教程,他反复强调不包括业务逻辑而不是.subscribe()方法 因此,我正在创建一个canActivate guard来防止用户进入无效路由,我不得不在subscribe方法中构建逻辑。有更好的方法吗 从'@angular/core'导入{Injectable}; 从'@angular/Router'导入{CanActivate,ActivatedRouteSnapshot,Router}; 从'rxjs/Subscription'导入{

我在看@john_lindquist关于RxJS的书呆子教程,他反复强调不包括业务逻辑而不是
.subscribe()
方法

因此,我正在创建一个canActivate guard来防止用户进入无效路由,我不得不在subscribe方法中构建逻辑。有更好的方法吗

从'@angular/core'导入{Injectable};
从'@angular/Router'导入{CanActivate,ActivatedRouteSnapshot,Router};
从'rxjs/Subscription'导入{Subscription};
从'rxjs/Subject'导入{Subject};
从“阿波罗角度”导入{Apollo,ApolloQueryObservable};
从“/ticket.model”导入{GQTicketId};
@可注射()
导出类TicketOutactivatorService实现CanActivate{
公众票;
private returnTrue:Subject=new Subject();
私家票认购:认购;
建造师(私人阿波罗:阿波罗,
专用路由器:路由器{}
canActivate(路由:ActivatedRouteSnapshot){
this.ticketSubscription=this.apollo.watchQuery({
查询:GQTicketId,
变量:{
_id:+route.params['id']
}
}).subscribe({data})=>{
this.ticket=数据['ticket'];
//至少根据约翰·林奎斯特(John Linquidst)的指导,这似乎不对。这种逻辑应该是“Rx'd”吗?
如果(!这张票){
this.router.navigate(['provision/requests/error/404']);
}否则{
this.returnTrue.next(true);
}
}
);
如果(this.returnTrue)返回true;
}
//我们需要退订吗?
ngOnDestroy():void{
此.ticketSubscription.unsubscribe();
}
}

为了回答您的问题,有一种更“RxJS友好”的方式来做您想做的事情。(“更好”是一个意见问题)。因此,例如,如果我正在实施这个,我会这样做:

canActivate(route: ActivatedRouteSnapshot) {

  // canActivate can return an Observable - 
  // the Observable emitting a true or false value
  // is similar to returning an explicit true or false
  // but by returning the observable, you let the router
  // manage the subscription (and unsubscription) instead of doing it yourself
  // doing this removes the need for the `unsubscribe` in your code
  return this.apollo.watchQuery({
    query: GQTicketId,
    variables: {
      _id: +route.params['id']
    }
  })
  // there should be no arguing about this point -
  // you only care about the data['ticket'] property,
  // not the entire data object, so let's map our observable
  // to only deal with ticket
  .map(response => response.data.ticket)
  // you want to do a side effect if ticket is falsy
  // so the do operator is your best friend for side effect code
  .do(ticket => {
    if(!ticket) {
      this.router.navigate(['provision/requests/error/404']);
    }
  })
}
没有注释:

canActivate(route: ActivatedRouteSnapshot) {

  return this.apollo.watchQuery({
    query: GQTicketId,
    variables: {
      _id: +route.params['id']
    }
  }).map(response => response.data.ticket)
    .do(ticket => {
        if(!ticket) {
          this.router.navigate(['provision/requests/error/404']);
        }
      })
    }

我看了约翰的视频,但现在记不起具体细节了。但是,RxJS的关键之处在于,通过正确使用操作符,通常可以删除大量命令式代码,否则这些代码将最终出现在
subscribe
方法中。这并不意味着使用
subscribe
本身就是不好的-只是
subscribe
中的逻辑通常表明您没有充分利用RxJS

要回答您的问题,有一种更“RxJS友好”的方式来做您想做的事情。(“更好”是一个意见问题)。因此,例如,如果我正在实施这个,我会这样做:

canActivate(route: ActivatedRouteSnapshot) {

  // canActivate can return an Observable - 
  // the Observable emitting a true or false value
  // is similar to returning an explicit true or false
  // but by returning the observable, you let the router
  // manage the subscription (and unsubscription) instead of doing it yourself
  // doing this removes the need for the `unsubscribe` in your code
  return this.apollo.watchQuery({
    query: GQTicketId,
    variables: {
      _id: +route.params['id']
    }
  })
  // there should be no arguing about this point -
  // you only care about the data['ticket'] property,
  // not the entire data object, so let's map our observable
  // to only deal with ticket
  .map(response => response.data.ticket)
  // you want to do a side effect if ticket is falsy
  // so the do operator is your best friend for side effect code
  .do(ticket => {
    if(!ticket) {
      this.router.navigate(['provision/requests/error/404']);
    }
  })
}
没有注释:

canActivate(route: ActivatedRouteSnapshot) {

  return this.apollo.watchQuery({
    query: GQTicketId,
    variables: {
      _id: +route.params['id']
    }
  }).map(response => response.data.ticket)
    .do(ticket => {
        if(!ticket) {
          this.router.navigate(['provision/requests/error/404']);
        }
      })
    }

我看了约翰的视频,但现在记不起具体细节了。但是,RxJS的关键之处在于,通过正确使用操作符,通常可以删除大量命令式代码,否则这些代码将最终出现在
subscribe
方法中。这并不意味着使用
subscribe
本身就是不好的-只是
subscribe
中的逻辑通常表明您没有充分利用RxJS

“我在看@john_lindquist关于RxJS的egghead教程,他反复强调不包括业务逻辑而不是.subscribe()方法。”-他的理由是什么?代码段中实现的一个主要问题是它假设
subscribe
是同步的。您应该从
canActivate
返回observable,并让路由器实现订阅它(如下面的答案所示)
canActivate
可以返回布尔值、承诺值或可观察值。“我在看@john_lindquist关于RxJS的egghead教程,他反复强调不包括业务逻辑而不是.subscribe()方法。”-他的理由是什么?代码段中实现的一个主要问题是它假设
subscribe
是同步的。您应该从
canActivate
返回observable,并让路由器实现订阅它(如下面的答案所示)
canActivate
可以返回布尔值、承诺值或可观察值。
do
运算符在RxJS 5.5中重命名为
tap
。请参阅RxJS 5.5中的
do
操作符重命名为
tap
。看见