2017-07-05 11 views
0

私は観測値とまだかなり混同しています。彼らは非常に複雑です。別の観測値に基づいてfirebaseリストを取得する方法

私は、監視対象リストとしてログインしているユーザーのアドレスを監視するために使用できるサービスクラスを作成しようとしています。問題は、ユーザーがログインまたはログアウトしたときにリスト参照自体が変更されたと思います。

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$が定義されていないと思うので、私はnullを取得していリストに加入者を追加してみてください。

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

ユーザーがログインしたときに新しい観測可能リストを発行する必要があります。 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()); 
     } 
    }); 
    } 

答えて

0

だから、あなたが何をしたいのか、擬似コードでは、これです:

  1. 最初にauthServiceを呼び出してユーザーIDを取得します。

  2. ユーザーが存在する場合は、データベース内のアドレスに移動して取得してください。

  3. そうでない場合は、何も返しません。

  4. 結果をaddresses$に割り当て、それを観測可能なものとして公開します。

このような手順を分解すると、Observablesが混乱することはありません。リストされた各タスクを実行する方法を知っている限り、あなたは良いです。あなたは擬似コードと比較できるように、私は、コード内のいくつかのインラインcommmentsをした

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

:ここ

はコードです。

+0

ああ私は、それは鎖のようなもので、約束事のようなものです。私はswitchMapがドキュメントで何をしているかを調べてみましょう。私はちょうど質問編集で投稿した作業をしましたが、これはより簡潔ですので、正しいとマークしますが、おそらく私の解決策に固執しています。それを変更するのは嫌です... –

+0

'。 switchMap()は約束の中で '.then()'と似ています。 – CozyAzure

+0

@リチャードGああ、ちょうどあなたの編集を見た。 「科目」もうまくいきます。 – CozyAzure

関連する問題