【问题标题】:How to get retrieve firebase list based on another observable如何根据另一个可观察到的检索 Firebase 列表
【发布时间】:2017-07-05 03:49:51
【问题描述】:

我仍然对 observables 感到很困惑。它们非常复杂。

我正在尝试编写一个服务类,该服务类可用于将登录用户的地址作为可观察列表进行监控。问题是我猜当用户登录或注销时列表引用本身会发生变化。

export class AddressService {
  user: any;
  addresses$: FirebaseListObservable<Address[]>;

  constructor(private db: AngularFireDatabase, private authService: AuthService) {
    authService.user$.subscribe((user) => {
      this.user = user;
      if (this.user) {
        this.addresses$ = this.db.list(`/users/${this.user.uid}/addresses`);
      } else {
        this.addresses$ = undefined;
      }
    });
  }
}

当我尝试将订阅者添加到列表时,我得到了 null,因为我猜 addresses$ 在添加时没有定义,因为它取决于登录用户首先解析。

// in a UI component
ngOnInit() {
  this.addresses = this.addressService.addresses$;
}

就像我需要一个新的 observable,它在用户登录时发出一个新的 observable 列表!正在查看http://reactivex.io/documentation/operators/switch.html - 也许这可以以某种方式工作?

此处已编辑更新 这就是我想出的(只是从课堂上提取的)

// users can monitor this to get the latest address book.
  addresses$: Observable<FirebaseListObservable<any>>;

  // keeps a reference to the address subject.
  private addressSubject = new BehaviorSubject<any>(Observable.empty());

  constructor(private db: AngularFireDatabase, private authService: AuthService) {
    this.addresses$ = this.addressSubject.asObservable();
    authService.user$.subscribe((user) => {
      this.user = user;
      if (this.user) {
        this.addressSubject.next(this.db.list(`/users/${this.user.uid}/addresses`));
      } else {
        this.addressSubject.next(Observable.empty());
      }
    });
  }

【问题讨论】:

    标签: angular rxjs angularfire2


    【解决方案1】:

    所以你想用伪代码做的是:

    1. 首先调用authService获取用户ID。

    2. 如果用户存在,去数据库中检索地址。

    3. 如果没有,则不返回任何内容。

    4. 将结果分配给addresses$,将其公开为可观察对象。

    如果您像这样分解这些步骤,那么您将不会发现 Observables 令人困惑。只要您知道完成列出的每项任务的方法,就可以了。

    代码如下:

    export class AddressService {
        user: any;
        addresses$: FirebaseListObservable<Address[]>;
    
        constructor(private db: AngularFireDatabase, private authService: AuthService) {
            //Step 4: assign the observable back to addresses$
            this.addresses$ =
                //Step 1: first call the auth service
                this.authService.user$.switchMap(user => {
                    this.user = user;
                    //Step 2: if user exist, call DB service
                    if (this.user) {
                        return this.db.list(`/users/${this.user.uid}/addresses`);
                    }
                    //Step 3: else just return nothing
                    else {
                        return Obsevable.empty()
                    }
                })
        }
    }
    

    我在代码中做了一些内联注释,方便大家对比伪代码。

    【讨论】:

    • 啊,我明白了,它有点像 promises 这样的链式可观察对象,很有趣。让我检查一下 switchMap 在文档中的作用。我刚刚在问题编辑中发布了它的工作,但这更简洁,所以我会标记它是正确的,但可能只是坚持我的解决方案,因为它正在工作,我不愿意改变它......
    • .switchMap() 就像承诺中的.then()
    • @RichardG 啊,刚刚看到你的编辑。有一个Subject 也很好用。
    • 其实我改了更好,因为它会立即返回地址列表。必须将addresses$设为Observable,否则它会给我一个编译器错误,我猜是因为Observable.empty()
    猜你喜欢
    • 1970-01-01
    • 2019-11-20
    • 2018-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    相关资源
    最近更新 更多