簡體   English   中英

角度RXJS結構可觀察

[英]Angular RXJS structuring observables

我有一個FeatureToggle守護程序,該函數調用FeatureToggle服務以獲取一系列功能切換,但我一直在努力尋找如何構造可觀察對象的方法,類似於我對諾言所做的操作。

守衛-

canActivate() {
   if(this.toggleService.hasToggles){
      return this.toggleService.isOn('my toggle');
   } else {
      return this.toggleService.getToggles().subscribe(() => {
         return this.toggleService.isOn('my toggle')
      })
   }
}

服務-

@Injectable    
export class ToggleService {
       private _toggles: string[];
       private _hasToggles: boolean;

       getToggles() {
          return this.http.get('...').subscribe((toggles) => {
             this._toggles = toggles;
          })
       }

       isOn(toggle) {
          // return if toggle is in this._toggles;
       }
    }

但是,由於我已經在該服務內部進行預訂,因此我將返回的是訂閱,而不是可觀察的。 我可以在getToggles創建對observable的本地引用,並返回該引用,但這是我應該使用的模式嗎?

您可以使用ReplaySubject重復上次發射值新的訂閱,然后有getToggles()調用http.get()只有一次。

https://www.learnrxjs.io/subjects/replaysubject.html

@Injectable({providedIn: 'root'})
export class ToggleService {
    private _toggles: ReplaySubject<string[]>;

    getToggles(): ReplaySubject<string[]> {
        if (!this._toggles) {
            this._toggles = new ReplaySubject();
            this.http.get('...').subscribe((toggles) => this._toggles.next(toggles));
        }
        return this._toggles;
    }

    isOn(toggle): Observable<boolean> {
        return this.getToggles().pipe(map(toggles => toggles.includes(toggle)));
    }
}

您還可以使用shareReply運算符:

https://www.learnrxjs.io/operators/multicasting/sharereplay.html

@Injectable({providedIn: 'root'})
export class ToggleService {
    private _toggles: Observable<string[]>;

    getToggles(): Observable<string[]> {
        if (!this._toggles) {
            this._toggles = this.http.get('...').pipe(shareReplay(1));
        }
        return this._toggles;
    }

    isOn(toggle): Observable<boolean> {
        return this.getToggles().pipe(map(toggles => toggles.includes(toggle)));
    }
}

使用Observable時,總是存在無法再傳遞Observable的邊緣。 在Angular中,它們可以傳遞到視圖模板中,並通過| async訂閱| async | async管道。 或者,在您的情況下,作為canActivate的返回值。 因此,在您的服務中使用Observables非常方便。

在服務中,如果要緩存結果,可以使用BehaviourSubject存儲它們,然后將它們作為Observable傳遞給其他對象。 或者,您可以使用shareReplay運算符創建一個可觀察shareReplay並重新使用它。 或者,簡單地,您可以將它們存儲起來並使用'rxjs'of函數將其返回。 我將說明最后一個選項。

@Injectable    
export class ToggleService {
   private _toggles: string[];
   private _hasToggles: boolean;

   getToggles(refresh?: boolean) {
      if (!refresh || !this.toggles) {
      return this.http.get('...').pipe(
        tap((toggles) => {
         this._toggles = toggles;
        });
      );
      } else {
        return of(this._toggles);
      }

   }

isOn您還可以返回boolean類型的Observable 這樣,您就可以盡可能地傳遞它。

   isOn(toggle): Observable<boolean> {
      return this.getToggles().pipe(
        map(toggles => toggles.includes(toggle))
      )
   }

canActivate變得非常簡單:

canActivate(): Observable<boolean> {
  return this.toggleService.isOn('my toggle');
}

Angular訂閱返回的observable。 無需檢查是否已加載切換開關-該服務已經解決了這一問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM