2017-01-20 1 views
3

Observableスタイルプログラミングの新機能です。私は質問がある:私は、コンポーネント間のアプリを介してユーザー情報を共有したい - と私はこの情報を共有するためにBehaviorSubjectを使用します。これは、AuthInfoとしてBehaviorSubjectを共有することによって影響を受けます。私のアプリケーションコンポーネントでuidを含むAuthInfoを共有できるのであれば、それを使って自分のユーザーオブジェクトデータを共有できますか?Observableをビヘイビアサブジェクトに簡単に変換または割り当てて他のコンポーネントがそれを共有できるようにする方法

問題は、ユーザーオブジェクトです、私はFirebaseから取得しています。それはObservableであり、どのようにこれをBehavior Subjectに割り当てることはできません。だからここに私がしようとしたコードです:

@Injectable() 
    export class AuthService { 

    static UNKNOWN_USER = new AuthInfo(null); 

    static EMPTY_USER = new User(null, null, null, null); 

    authInfo$: BehaviorSubject<AuthInfo> = new BehaviorSubject<AuthInfo>(AuthService.UNKNOWN_USER); 

    userInfo$: BehaviorSubject<User> = new BehaviorSubject<User>(AuthService.EMPTY_USER); 

    constructor(private auth: FirebaseAuth, private db:AngularFireDatabase, @Inject(FirebaseRef) fb) { 

//firebase way to see if user is login or not 
this.auth.subscribe(user => { 
    if (user) { 
    const authInfo = new AuthInfo(user.uid); 
    this.authInfo$.next(authInfo); 
    //This is the part I do not know how to do 
    [OPTION 1]: this.userInfo$.next(findUserByuid(user.uid)) ?? - error 
    [OPTION 2]: this.userInfo$ = findUserByuid(user.uid) ?? - userInfo$ turn into an observerable, which when I logout to call this.userInfo$.next(AuthService.EMPTY_USER) it will throw error as .next() is not a function. 
    [OPTION 3]: 
    this.findUserByuid(user.uid).subscribe(user => { 
     this.userInfo$.next(user); 
    }); 
    ---- Can I put a subscribe inside of another subscribe to chain it like promise? I am not sure this is following the best practices. But this is the only option that there is no error. But just not sure I am doing it right. I do get the user object no problem 

    } 
    else { 
    this.authInfo$.next(AuthService.UNKNOWN_USER); 
    } 
}); 


} 

findUserByuid(uid:string):any { 
    //return a firebase object observerable 
    return this.db.object('userProfile/' + uid).map(user => User.fromJson(user)); 

} 

logout() { 

this.userInfo$.next(AuthService.EMPTY_USER); 
this.authInfo$.next(AuthService.UNKNOWN_USER); 
this.auth.logout(); 
} 

そして大きな疑問は、私が行動の対象を使用してアプリケーション間でデータを共有する必要がありますか?または、私はちょうどuser $ = findUserByuid(uid)のようなobservableを使って、User $をAuthServiceのメンバ変数として使うべきですか?そして、他のコンポーネントはユーザー$に加入していますか?

Angular1のようなダミーサービスを使わずに、Angular2でデータを共有するための最良の方法を非常に混乱しています。私はpplがBehavior Subjectを使って共有状態を共有するのを見ました。実装。どんな助けでも大歓迎です!行動主題に関してそこには多くのリソースがありません。

[UPDATE]:アプリケーション間で最良の方法2共有データは、それがReduxのを使っている私の意見で Behavior Subject VS regular Observable

答えて

2

これは、私はそれを書くだろうかです:

... 

authInfo$: Observable<AuthInfo>; 
userInfo$: Observable<User>; 

constructor(private auth: FirebaseAuth, private db:AngularFireDatabase, @Inject(FirebaseRef) fb) { 
    //firebase way to see if user is login or not 
    this.authInfo$ = auth 
    .startWith(null) // in case auth has no initial value 
    .map(user => user ? new AuthInfo(user.uid) : AuthService.UNKNOWN_USER) 
    .publishReplay(1) 
    .refCount(); 

    // automatically update the unserInfo$ when authInfo$ changes (no matter from where) 
    // ...we are "reacting" on the data emitted by authInfo$ ... hence the name "reactive" programming 
    this.userInfo$ = this.authInfo$ 
    .switchMap(authInfo => this.findUserByuid(authInfo.uid)) 
    .publishReplay(1); 

    // this activates the whole stream-flow 
    this.userInfo$.connect(); // instead of .connect() you could also append a ".refCount()" after the ".publishReplay(1)", however then it would only be acitve when there is at least 1 subscriber, so it depends on what you want 
} 

findUserByuid(uid?: string): Observable<User> { 
    if (uid == null) { 
    return Observable.of(AuthService.EMPTY_USER); 
    } else { 
    return this.db.object('userProfile/' + uid) 
     .map(user => User.fromJson(user)); 
    } 
} 

logout() { 
    this.auth.logout(); 
} 

... 
+0

こんにちは@Olsn、あなたは行動を使用するように提案していませんテーマ? this.authInfo $に初期値がなくても、他の新しいコンポーネントがauthInfo $とuserInfo $の最新の値を取得していない可能性があります。だから私は行動主題を使用する必要があります。ここでObservableだけを使用する理由を説明できますか? –

+0

Afaik 'FirebaseAuth'は既にReplaySubjectですので、初期値がなければ' .startWith(null) 'を使うことができます。 – olsn

+0

ありがとうございました。結合された質問。 FirebaseAuthがReplaySubjectであることをどのように知っていますか?あなたはそれを述べている場所に私を向けることができますか?また、データはfirebase.database.listと.objectを使ってReplaySubjectを取得しますか?私は.publishReplay(1).refCount();と仮定します。 this.authInfo $をキャッシュします。しかし、ユーザーログアウト時にauthInfo $が変更されます。だから私はその機能を失った。ユーザーログアウトと値が変更されたときにキャッシュを更新するにはどうすればよいですか?そして、これは行動の主題に変わることがありますので、私は理解しています。行動主題の例だけを学び、Repalyの主題については分かりません。ありがとう! –

1

:私のアプリの異なる部分の間でデータを渡すために、私だけではなく、観察の行動対象を選択した理由パターン2では、ngrx/storeとngrx/effectsを実装しています。スマートな構成要素とプレゼンテーション要素のパターン。

は、私はそれらのパターンhttps://github.com/vigohe/ionic2-marvelApp

との例を持っている私の実行している例:

https://github.com/ngrx/example-app

:ngrxレポから

https://enigmatic-plains-75996.herokuapp.com/

公式の例

詳細情報:

それはあなたの人生が変わりますので、それを学ぶにしてください;)

+0

ご提案いただきありがとうございます。面白いのは、チャットアプリ(あなたのリンクの1つに含まれています)上の有料大学のウェブサイトを介してngrx/storeを学習していることです。しかし、ngrx/storeの周りに私の脳を包み込むことはまだ非常に難しいです。私の大きな問題の1つは、angularfire/Firebaseでngrx/store reduxパターンを使用することです。これは、観測可能なプログラミング言語で書かれています。 Firebase(Auth、CRUD、その他の操作)でngrx/storeを使用する方法を学ぶためのリソースはありますか?私はそれを正しく使用する方法を学ぶことができるなら、私はそれを使いたいです。それでも、私は100%あなたに同意しています。 –

+0

ngrx [example-app](https://github.com/ngrx/example-app)から学びましょう。これは素晴らしいチュートリアルです。この[コース](https://egghead.io/courses)をチェックすることもできます/ egg-machine-with-angular-2-and-rxjs)egghead.ioから あなたはngrx/effectsを学ぶ必要があります –

関連する問題