[英]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.