Angular 角RXJS结构可观测值

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

我有一个FeatureToggle guard,它调用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
中创建对可观察对象的本地引用并返回该引用,但这是我应该使用的模式吗?

您可以使用
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');
}