Angular 角RXJS结构可观测值
我有一个FeatureToggle guard,它调用FeatureToggle服务来获得一系列功能切换,但我正努力弄清楚如何构建观察对象,就像我在承诺中所做的那样 警卫-Angular 角RXJS结构可观测值,angular,rxjs,observable,Angular,Rxjs,Observable,我有一个FeatureToggle guard,它调用FeatureToggle服务来获得一系列功能切换,但我正努力弄清楚如何构建观察对象,就像我在承诺中所做的那样 警卫- canActivate() { if(this.toggleService.hasToggles){ return this.toggleService.isOn('my toggle'); } else { return this.toggleService.getToggles().s
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
中创建对可观察对象的本地引用并返回该引用,但这是我应该使用的模式吗?您可以使用ReplaySubject
为新订阅重复上一次发出的值,然后让getToggles()
调用http.get()
在处理可观察对象时,始终存在无法再通过
可观察对象
的边缘。在Angular中,它们可以传递到视图模板,通过|async
管道订阅它们。或者,在您的情况下,作为canActivate
的返回值。因此,在您的服务中使用可观测数据非常方便
在您的服务中,如果您想要缓存结果,您可以使用behavior subject
存储它们,然后将它们作为可观察的进一步传递。或者您可以使用shareReplay
操作符创建一个observable并重新使用它。或者,简单地说,您可以将它们存储起来,然后使用'rxjs'
的函数返回它们。我将举例说明最后一个选项
@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
中,还可以返回布尔类型的可观察的。这样你就可以尽可能地通过它
isOn(toggle): Observable<boolean> {
return this.getToggles().pipe(
map(toggles => toggles.includes(toggle))
)
}
返回的可观测值的角度下标。不需要检查切换是否已经加载-服务已经处理了这个问题。服务应该返回可观察的:getToggles(){返回this.http.get(…);}
。我希望服务是可注入的,这将保留应用程序其他部分使用的切换列表?我不明白为什么你必须在你的防护装置内订阅。看起来你可以使用映射(()=>this.toggleService.isOn('my toggle'))
并返回它。我想这正是我想要的,点击
提供了一种在传递可观察到的信息时产生副作用的方法。我会试一试的,谢谢@cgTag的回答还说明了另外两个选项,这两个选项看起来可能更难理解,但最终会更清晰。
@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(toggle): Observable<boolean> {
return this.getToggles().pipe(
map(toggles => toggles.includes(toggle))
)
}
canActivate(): Observable<boolean> {
return this.toggleService.isOn('my toggle');
}