2016-11-10 37 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';