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