2016-11-10 35 views
3

我有2個服務。在一個我想訂閱檢測是否一個字符串中的其他服務更改每次更改時從數據庫加載。Angular 2如何使用observable檢測字符串更改

首先服務:(使用的會話值是參照第2層服務)

subscribeStringChange() { 
    this.session.uid.subscribe(x => { 
     console.log(this.session.uid); 
     return this.af.database.list('items', { 
      query: { 
       orderByChild: 'uid', 
       equalTo: this.session.uid 
      } 
     }); 
    }); 
} 

這裏是第二個服務,什麼我都試過:

uid: Observable<string> = Observable.of(''); 

constructor(private auth: FirebaseAuth, private af: AngularFire) { 
    this.auth.subscribe(user => { 
     if (user) { 
      this.uid = Observable.of(user.uid); 
      console.info('logged in'); 
     } else { 
      this.uid = Observable.of(''); 
      console.info('logged out'); 
     } 
    }); 
} 

回答

1

你可以使用一個BehaviorSubject,這就像既是生產者和消費者(或更確切地說,是觀察者和可觀察的)。在您使用火力的一面,你會作用於製片方,散發出新的價值,而在另一邊,你只要保持同一

import { BehaviorSubject } from 'rxjs/BehaviorSubject'; 

private _uid = new BehaviorSubject<string>(''); 

uid = this._uid.asObservable(); 

constructor(private auth: FirebaseAuth, private af: AngularFire) { 
    this.auth.subscribe(user => { 
     if (user) { 
      this._uid.next(user.uid); 
      console.info('logged in'); 
     } else { 
      this.uid.next(''); 
      console.info('logged out'); 
     } 
    }); 
} 

通知的this._uid.next('')。在這裏你發出一個新的值,用戶將收到它。

您不需要更改其他服務中的任何內容。實際上你是這麼做的。您試圖訪問uid,這是一個可觀的,當你應該只使用傳遞給訂閱回調的價值,x

this.session.uid.subscribe(x => { 
    console.log(x); 
    return this.af.database.list('items', { 
     query: { 
      orderByChild: 'uid', 
      equalTo: x 
     } 
    }); 
}); 
1

你所做的事比較複雜,那麼他們應該是(一般來說,你應該使用subscribe()來將可觀察鏈的最終結果分配給一個變量(例如用於模板)。你不應該在訂閱中處理觀察值...

這裏有一個解決方案,您可以使用:

subscribeStringChange() { 
    // when user is authenticated 
    this.af.auth.filter(Boolean) 
    // get her 'uid' 
    .map(user => user.uid) 
    // and use it in another observable 
    .switchMap(uid => this.af.database.list('items', { 
      query: { 
       orderByChild: 'uid', 
       equalTo: uid 
      } 
     }) 
    // finally, do something with the results 
    .subscribe(snap => console.log(snap)); 
} 

確保導入運營商的地方在你的代碼,在這種情況下:

import 'rxjs/add/operator/filter'; 
import 'rxjs/add/operator/map'; 
import 'rxjs/add/operator/switchMap';