【问题标题】:Conditionally emit observable有条件地发出 observable
【发布时间】:2017-08-17 11:46:47
【问题描述】:

我们有一个带有 Redux (ngrx 4) 的 Angular 4 应用程序。

我们将“isLoggedIn”信息保存在ngrx/store中,当我们调用http时,我们必须首先检查他是否经过身份验证。

我们正在努力实现进行 http 调用的服务:

export class GetDataFromREST() {

     constructor(private http: HttpClient, private loginStore: Store) {
          this.loggedIn$ = this.loginStore.select(getLoggedIn);
     }
     ...
     public getProducts(): Observable<ProductList> {

          return /*observable that returns http.get(api) only 
                   after the loggedIn$ emits true */
     }
}

请注意,登录不应该是服务的问题 - 一旦登录,它应该执行从它请求的所有调用。

有什么想法吗?

【问题讨论】:

  • 你所说的“执行所有从它那里询问的调用”是什么意思。
  • 我误解了你的要求 - 为什么不只是在 getProducts() 方法中进行布尔检查 (isLoggedIn),然后调用 API 或返回一个空的 observable
  • 如果应用在商店中将IsLoggedIn 设置为true 之前向getProducts() 发出调用,则调用不应失败(或返回空)。它应该等到值得到true,然后将http.get 返回给调用者。我希望这可以澄清它?

标签: angular rxjs observable ngrx ngrx-store


【解决方案1】:

这将达到您要求的结果。

export class GetDataFromREST() {

     constructor(private http: HttpClient, private loginStore: Store) {
          this.loggedIn$ = this.loginStore.select(getLoggedIn);
     }
     ...
     public getProducts(): Observable<ProductList> {

          return this.loggedIn$.filter(Boolean).take(1).subscribe(
            () => http.get(api)
          )
     }
}

【讨论】:

  • 这将调用每次商店更改时发出的每个http.get(这在redux中非常频繁)
  • 不错的...而且很简单!像魅力一样工作 - 谢谢!
【解决方案2】:

由于loggedIn$ 已经是一个 Observable,您可以重放它的最后一个值并将其用作将与远程调用合并的源 Observable:

this.loggedIn$ = this.loginStore.select(getLoggedIn)
  .publishReplay(1)
  .refCount();

...

public getProducts(): Observable<ProductList> {
  return this.loggedIn$
    .mergeMap(() => http.get(api));
}

所以getProducts()this.loginStore.select(getLoggedIn) 发出之前不会发出任何东西。

此外,当您稍后调用 getProducts() 时,this.loggedIn$ 中的最新值将被重播,因此它会立即运行远程调用。

【讨论】:

    【解决方案3】:

    使用 CombineLatest 操作符将 log in observable 与 get api observable 结合起来,然后您可以按登录状态进行过滤

    http://reactivex.io/documentation/operators/combinelatest.html http://reactivex.io/documentation/operators/filter.html

    【讨论】:

    • 如果我们这样做return this.loggedIn$.combineLatest( ... );,这不会在每次商店更新时发出一个http调用吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-11
    • 2017-03-09
    • 1970-01-01
    • 2019-03-30
    • 2021-01-13
    • 2016-06-23
    • 1970-01-01
    相关资源
    最近更新 更多