如何根据另一个observable获取firebase列表

时间:2017-07-05 03:49:51

标签: angular rxjs angularfire2

我仍然对可观察者很困惑。他们非常复杂。

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

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

1 个答案:

答案 0 :(得分:0)

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

  1. 首先致电authService以检索用户ID。

  2. 如果用户存在,请转到并检索数据库中的地址。

  3. 如果没有,只需返回任何内容。

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

  5. 如果你按照这样的步骤分解,那么你就不会发现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()
                    }
                })
        }
    }
    

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