[Angular] Reactive Store and AngularFire Observables

A simple store implemenet:

import { Observable } from 'rxjs/Observable';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

import 'rxjs/add/operator/pluck';
import 'rxjs/add/operator/distinctUntilChanged';
import {User} from './auth/shared/services/auth/auth.service';

export interface State {
  user: User;
  [key: string]: any
}

const state: State = {
  user: undefined
};

export class Store {

  private subject = new BehaviorSubject<State>(state);
  private store = this.subject.asObservable().distinctUntilChanged();

  get value() {
    return this.subject.value;
  }

  select<T>(name: string): Observable<T> {
    return this.store.pluck(name);
  }

  set(name: string, state: any) {
    this.subject.next({ ...this.value, [name]: state });
  }

}

Using this store in AuthService:

import {Injectable} from '@angular/core';
import {AngularFireAuth} from 'angularfire2/auth';
import {Store} from 'store';

import 'rxjs/add/operator/do';

export interface User {
  uid: string;
  email: string;
  authenticated: boolean;
}

@Injectable()
export class AuthService {

  // handle on every auth state changes
  auth$ = this.af.authState
    .do(next => {
      if (!next) {
        this.store.set('user', null);
        return;
      }
      const user = {
        email: next.email,
        uid: next.uid,
        authenticated: true
      };
      this.store.set('user', user);
    });

  constructor(
    private af: AngularFireAuth,
    private store: Store
  ) {

  }

  createUser(email: string, password: string) {
    return this.af.auth.createUserWithEmailAndPassword(email, password);
  }

  loginUser(email: string, password: string) {
    return this.af.auth.signInWithEmailAndPassword(email, password)
  }
}

Using Reactive approach in app.component.ts:

import {Component, OnDestroy, OnInit} from '@angular/core';
import {Store} from 'store';
import {AuthService} from '../../../auth/shared/services/auth/auth.service';

import {Observable} from 'rxjs/Observable';
import {Subscription} from 'rxjs/Subscription';
import {User} from 'firebase/app';

@Component({
  selector: 'app-root',
  styleUrls: ['app.component.scss'],
  template: `
    <div>
      <h1>{{user$ | async | json}}</h1>
      <div class="wrapper">
        <router-outlet></router-outlet>
      </div>
    </div>
  `
})
export class AppComponent implements OnInit, OnDestroy{

  user$: Observable<User>;
  subscription: Subscription;

  constructor(
    private store: Store,
    private authService: AuthService
  ) {}

  ngOnInit() {
    this.subscription = this.authService.auth$.subscribe();
    this.user$ = this.store.select<User>('user');
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}
原文地址:https://www.cnblogs.com/Answer1215/p/7295342.html