2017-04-12 44 views
1

我在RxJS上觀看了@ john_lindquist的egghead教程,他強調了不包括商業邏輯而不是.subscribe()方法的觀點。可以在Observable訂閱方法中包含邏輯嗎?

因此,我創建了一個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(); 
    } 

} 
+0

_「我在看RxJS上的@ john_lindquist的egghead教程,他強調了不包括busienss邏輯而不是.subscribe()方法的觀點。」_ - 他的推理是什麼? –

+0

在代碼片段中實現的一個主要問題是它假定'subscribe'是同步的。您應該從'canActivate'返回observable並讓路由器實現訂閱它(如下面的答案)。 'canActivate'可以返回布爾值,承諾或可觀察值。 – cartant

回答

4

要回答你的問題,有一個更'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中有邏輯通常表示您沒有使用RxJS發揮其最大潛力。

+0

這樣做很有意義,非常感謝! – techtrek