首页 > 解决方案 > ngrx 文档参考分辨率

问题描述

我尝试使用ngrx 和firestore 来实现一个朋友系统。

因此,我创建了一个包含/users用户信息的集合,例如姓名、头像图片链接、在线状态等。第二部分由/users/{id}/buddies每个用户的集合组成,其中包含仅包含朋友的朋友信息

此设置允许为每个用户朋友收集最少的集合,而无需跟踪buddies表中用户信息的副本。

设置和上下文就这么多。

我在解决个人朋友的用户文档参考方面遇到了很多问题......理想情况下,我希望拥有一个好友商店,其中包含当前用户的所有好友,并且可以使用各种选择器进行选择。

Buddy 模型应该类似于:

export interface Buddy {
  uid: string;
  buddyStatus: BuddyStatus;
  userRef: User | any;
}

User模型如下所示:

export enum AuthState {
  LOGGED_IN = "LOGGED_IN",
  NOT_LOGGED_IN = "NOT_LOGGED_IN"
};

export interface User {
  uid: string | null;
  displayName: string | null;
  authState: AuthState;
  loading?: boolean;
  error?: string | null;
  avatarUrl: string | null;
};

通过侦听状态更改并调度相应的ngrx 存储操作(添加、修改、删除),将伙伴存储同步到firestore 数据库:

  query$ = createEffect(() => this.actions$.pipe(
    ofType(BuddiesActions.query),
    switchMap(() => {
      return this.uid$.pipe(
        switchMap(uid => {
          return this.afs.collection(`users/${uid}/buddies`).stateChanges();
        })
      )
    }),
    mergeMap(actions => {
      return actions;
    }),

    // map the firestore actions to ngrx store actions to sync them
    // TODO this adds the user reference and things fuck up here...
    map((action: DocumentChangeAction<any>) => {

      const data = action.payload.doc.data();


      console.log({data: data});
      return {
        type: `[Buddies] ${action.type}`,
        buddy: {
          buddyStatus: data.buddyStatus,
          uid: data.uid,
          // this is the issue right here
          // userRef: data.userRef
        }
      };
    })
  ));

如果没有参考字段,则可以正确处理好友,但对好友的访问对于显示至关重要:在线状态、获取头像 url 等。

我设法同步检索某个用户的好友,但这并不是真正的方法,因为我想在用户状态等中包含更改器。

我对ngrx / angular和typescript相当陌生,这基本上是我使用这些工具/框架/概念的第一个大项目。

我检查了其他答案,但它们中的大多数都可以同步解析引用,但这并不是真正的目标,因为需要对用户信息进行观察。

标签: angularngrx

解决方案


来吧,我用一种方法来解决ngrx中的此类问题。

当你对好友进行更改时,不要听好友的更改。将该侦听器作为一个单独的侦听器。然后在触发任何操作时对好友执行任何查询。无需担心立即采取行动的变化。始终从 firestore 获取数据并更新本地存储。

 createEffect(() => this.actions$.pipe(
    ofType(BuddiesActions.query),
    switchMap(() => {
      return this.uid$.pipe(
        switchMap(uid => {
          return this.firestoreService.buddyQuery(uid)
        })
      )
    })

保持与查询相关的效果不变,并在那里删除不需要的好友日期获取调用,这些调用获取好友数据。

然后你需要引入一些动作,比如“监听好友更改”来监听数据库更改。

 createEffect(() => this.actions$.pipe(
    ofType(BuddiesActions.Listen_ON_BUDDY_CHANGES),
    switchMap(() => {
   // add listner to firestore and trigger that observable when any data changes happend

  const data = action.payload.doc.data();

  console.log({data: data});
  return {
    type: `[Buddies] ${action.type}`,
    buddy: {
      buddyStatus: data.buddyStatus,
      uid: data.uid,
    }
  };

这应该是一个监听 firestore 中所有变化的 observable。当那里发生任何更改时,然后直接使用该数据更新本地 ngrx 存储。正如您所料,这是一个异步操作。确保在初始步骤中触发“监听好友更改”操作。


推荐阅读