Angular Firestore 的行为主体

Angular Behaviour Subject with Firestore

对 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> 

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

服务

您的服务将负责定义和 return 链接到您的 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

正如您自己所建议的那样,您在模板中订阅了您的 observable。

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