Firestore的角行为主题

时间:2018-10-02 09:30:24

标签: angular google-cloud-firestore angular2-observables

对于BehaviourSubjects来说是新奇的,并且不确定我是否已采用最佳方法。

我创建了一个查询Firestore的服务。我试图根据返回的数据创建一个BehaviourSubject,以便可以在多个组件中使用它。确保每个组件始终获得最新更新版本的最佳方法是什么?

我的应用程序的某些部分将使用新值更新Firestore。发生这种情况时,它会自动通过服务同步到我的组件中吗?

任何最佳实践示例或如何以良好的方式使它正常工作将不胜感激。谢谢!

服务

import { Injectable } from '@angular/core';
import { Observable, BehaviorSubject } from 'rxjs';
import { AngularFirestore, AngularFirestoreDocument } from '@angular/fire/firestore';

@Injectable({
  providedIn: 'root'
})
export class SettingsService {

  private settingsDocRef: AngularFirestoreDocument<any>;


  settingsDocument = new BehaviorSubject(this.settingsDocRef);
  settings$: Observable<any> = this.settingsDocument.asObservable();

  constructor(private readonly afs: AngularFirestore) {
    this.settingsDocRef = this.afs.doc(`user_settings/useridishere`);
    this.settings$ = this.settingsDocRef.snapshotChanges();
    this.settings$.subscribe((value) => {
      const data = value.payload.data();
      this.settingsDocument.next(data);
    });
  }
}

Component.ts

import { Component, OnInit } from '@angular/core';
import { SettingsService } from '../settings.service';
import { Observable } from 'rxjs';

@Component({
  selector: 'app-hello',
  templateUrl: './hello.component.html',
  styleUrls: ['./hello.component.css']
})

export class HelloComponent implements OnInit {

  issueName: string;

  // OR should this be an observable?
  // issueName: Observable<string>


  constructor(private settingsService: SettingsService ) {}

  ngOnInit() {
     this.settingsService.settings$.subscribe((settings) => {
      this.issueName = settings.usersetting_issuename;
    })
  }

}

HTML

<div>
  {{ issueName }}
</div> 

<!-- OR if it's supposed to be an observable? -->
<div>
  {{ issueName | async }}
</div> 

1 个答案:

答案 0 :(得分:0)

您无需在服务中使用主题来跟踪数据。只有当前已加载的组件需要订阅您的数据。

服务

您的服务将负责定义并返回链接到您的Firestore数据库的可观察对象。

import { Injectable } from '@angular/core';
import { Observable} from 'rxjs';
import { AngularFirestore, AngularFirestoreDocument } from '@angular/fire/firestore';

@Injectable({
  providedIn: 'root'
})
export class SettingsService {


  constructor(private readonly afs: AngularFirestore) {}

  getUserSettings(userID: string): Observable<any> {
      const settingsDocRef = this.afs.doc(`user_settings/${userID}`);
      return settingsDocRef.valueChanges();
  }
}

由于您只需要文档数据,所以我使用了valueChanges()而不是snapshotChanges()。

Component.ts

    import { Component, OnInit } from '@angular/core';
    import { SettingsService } from '../settings.service';
    import { Observable } from 'rxjs';

    @Component({
      selector: 'app-hello',
      templateUrl: './hello.component.html',
      styleUrls: ['./hello.component.css']
    })

    export class HelloComponent implements OnInit {

      issueName$: Observable<string>;

      constructor(private settingsService: SettingsService ) {}

      ngOnInit() {
         this.issueName$ = this.settingsService.getUserSettings('yourUserID').pipe(
             map((settings) => settings.usersetting_issuename)
         );
      }

    }

我没有添加实现以获取您的用户ID。您需要自己弄清楚还是要问另一个问题。

HTML

正如您自己建议的那样,您订阅了模板中的可观察对象。

<!-- OR if it's supposed to be an observable? -->
<div>
  {{ issueName$ | async }}
</div>