如何根据另一个可观察对象获取检索 firebase 列表

How to get retrieve firebase list based on another observable

我对 observables 还是很困惑。它们非常复杂。

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

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;
      }
    });
  }
}

当我尝试将订户添加到列表时,我得到的是空值,因为我猜 addresses$ 在添加时未定义,因为它取决于登录用户首先解析。

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

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

在此处编辑更新 这是我想出的(刚从 class 中提取)

// 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());
      }
    });
  }

所以你想要做的,在伪代码中,是这样的:

  1. 首先调用 authService 检索用户 ID。

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

  3. 如果没有,就return没什么。

  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()
                }
            })
    }
}

我在代码中做了一些内联注释,以便您可以与伪代码进行比较。