可以在 Observable 订阅方法中包含逻辑吗?
Is it ok to include logic inside an Observable subscribe method?
我在看@john_lindquist 关于 RxJS 的 egghead 教程,他强调了不包括业务逻辑而不是 .subscribe()
方法的观点。
所以我正在创建一个 canActivate 保护程序来防止用户转到无效路由,我不得不在订阅方法中构建逻辑。有更好的方法吗?
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, Router } from '@angular/router';
import { Subscription } from 'rxjs/Subscription';
import { Subject } from 'rxjs/Subject';
import { Apollo, ApolloQueryObservable } from 'apollo-angular';
import { GQTicketId } from './ticket.model';
@Injectable()
export class TicketRouteActivatorService implements CanActivate {
public ticket;
private returnTrue: Subject<Boolean> = new Subject<Boolean>();
private ticketSubscription: Subscription;
constructor(private apollo: Apollo,
private router: Router) { }
canActivate(route: ActivatedRouteSnapshot ) {
this.ticketSubscription = this.apollo.watchQuery({
query: GQTicketId,
variables: {
_id: +route.params['id']
}
}).subscribe(({data})=>{
this.ticket = data['ticket'];
// this doesn't seem right, atleast based on the guidance from John Linquidst. Should this logic be "Rx'd" some how?
if(!this.ticket) {
this.router.navigate(['provision/requests/error/404']);
} else {
this.returnTrue.next(true);
}
}
);
if (this.returnTrue) return true;
}
// do we need to unsubscribe?
ngOnDestroy():void {
this.ticketSubscription.unsubscribe();
}
}
要回答您的问题,还有一种更 'RxJS-friendly' 的方法可以满足您的需求。 ("Better"见仁见智)。所以,例如,如果我要实现这个,我会这样做:
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']);
}
})
}
我看过 John 的视频,但现在不记得具体内容了。但是,RxJS 的关键要点在于,通过正确使用运算符,您通常可以删除大量命令式代码,否则这些代码最终会出现在 subscribe
方法中。这并不意味着使用 subscribe
本身是不好的——只是在 subscribe
中具有逻辑通常表明您没有充分发挥 RxJS 的潜力。
我在看@john_lindquist 关于 RxJS 的 egghead 教程,他强调了不包括业务逻辑而不是 .subscribe()
方法的观点。
所以我正在创建一个 canActivate 保护程序来防止用户转到无效路由,我不得不在订阅方法中构建逻辑。有更好的方法吗?
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, Router } from '@angular/router';
import { Subscription } from 'rxjs/Subscription';
import { Subject } from 'rxjs/Subject';
import { Apollo, ApolloQueryObservable } from 'apollo-angular';
import { GQTicketId } from './ticket.model';
@Injectable()
export class TicketRouteActivatorService implements CanActivate {
public ticket;
private returnTrue: Subject<Boolean> = new Subject<Boolean>();
private ticketSubscription: Subscription;
constructor(private apollo: Apollo,
private router: Router) { }
canActivate(route: ActivatedRouteSnapshot ) {
this.ticketSubscription = this.apollo.watchQuery({
query: GQTicketId,
variables: {
_id: +route.params['id']
}
}).subscribe(({data})=>{
this.ticket = data['ticket'];
// this doesn't seem right, atleast based on the guidance from John Linquidst. Should this logic be "Rx'd" some how?
if(!this.ticket) {
this.router.navigate(['provision/requests/error/404']);
} else {
this.returnTrue.next(true);
}
}
);
if (this.returnTrue) return true;
}
// do we need to unsubscribe?
ngOnDestroy():void {
this.ticketSubscription.unsubscribe();
}
}
要回答您的问题,还有一种更 'RxJS-friendly' 的方法可以满足您的需求。 ("Better"见仁见智)。所以,例如,如果我要实现这个,我会这样做:
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']);
}
})
}
我看过 John 的视频,但现在不记得具体内容了。但是,RxJS 的关键要点在于,通过正确使用运算符,您通常可以删除大量命令式代码,否则这些代码最终会出现在 subscribe
方法中。这并不意味着使用 subscribe
本身是不好的——只是在 subscribe
中具有逻辑通常表明您没有充分发挥 RxJS 的潜力。