【问题标题】:Minimise UI changes based on document in query change根据查询更改中的文档最小化 UI 更改
【发布时间】:2020-07-01 16:27:46
【问题描述】:

我正在使用 AngularFire 开发一个使用嵌套数据的 Angular 应用程序。我目前有一个(嵌套)查询来获取父级及其子级数据,但这会导致 Angular 每次有一个子级数据点更新时重新创建父级组件。

数据的结构类似于:

Fields
  - Stories
    - Comments

将嵌套数据放置在 Firebase 内的子集合中。因此,评论可能具有如下路径:

database/fields/fieldId/stories/storyId/comments/commentId

为了创建一个字段对象(显示在 UI 中),我使用 rxjs 的 switchMap 如下:

ngOnInit() {
  this.getField(this.fieldID).subscribe(field => this.field = field);
}

getField(id: any): Observable<Field> {
  return this.getItem<Field>(id, 'fields').pipe(
    switchMap(field => {
      const nextPath = `fields/${field.id}/stories`;
      return getStories(nextPath).pipe(tap(stories => field.stories = stories));
    })
  );
}

getStories(path: string): Observable<Story[]> {
  return this.getItems<Story>(path).pipe(
    switchMap(stories => {
      stories.map(story => {
        let nextPath = `${path}/${story.id}/comments`;
        return getComments(nextPath).pipe(tap(comments => field.comments = comments));
      });
    })
  );
}

getComments(path: string): Observable<Comment[]> {
  return this.getItems<Comment>(path).pipe(
    switchMap(comments => {
      comments.map(comment => getComments(nextPath));
    })
  );
}

使用以下 getItem 和 getItems 函数:

getItem<T>(id: string, collectionName: string): Observable<T> {
  return this.fireDb
    .collection<T>(collectionName)
    .doc<T>(id)
    .snapshotChanges()
    .pipe(map(item => this.itemFromDocument(item)));
}

getItems<T>(collectionName: string): Observable<T[]> {
  return this.fireDb
    .collection<T>(collectionName)
    .snapshotChanges()
    .pipe(map(items => items.map(item => this.itemFromCollection(item))));
}

请注意,这是实际代码的简化版本,其中包括限制、过滤器以及一些更复杂的查询,如果上面有任何错误,敬请见谅。无论如何,数据库函数都可以工作,我可以使用调用获取包含嵌套信息的字段。

我遇到的问题是,每次修改或添加单个评论时,都会重新创建整个字段,我认为这会触发 Angular 重新构建依赖于该字段的所有组件。这会导致在重新创建父容器时清除输入字段等内容。

我的问题是:构建这些调用以避免每次更改都重新创建字段的最佳方法是什么?

我考虑了以下选项:

  1. 删除嵌套的 switchMap 调用。相反,从函数的根目录进行这些调用,并在调用完成时简单地更新数据。
  2. 修改数据后,仅识别已更改的数据点并单独更新它们。
  3. 停止依赖列表查询,以某种方式直接查询单个集合文档。
  4. 收到数据后关闭初始订阅,然后在本地处理任何更改。
  5. 以上的一些组合。

那么,有没有建议的方法来处理上述情况?我非常感谢任何建议或建议!

【问题讨论】:

    标签: javascript firebase google-cloud-firestore rxjs angularfire2


    【解决方案1】:

    这是我正在尝试的解决方案:

    1. 订阅第一次获取字段,然后关闭订阅。
    2. 使用嵌套的字段值,为每个文档创建单独的观察者。如果对它们进行更改,它们会更新各个文档。
    3. 创建一个过滤查询,用于侦听任何子集合中新创建的文档(使用类似https://github.com/firebase/firebase-js-sdk/issues/1551)。

    我仍然确信一定有一个更优雅的解决方案。这个解决方案也很可能会产生一些长期的负面影响,所以如果我遇到任何问题,我会添加评论。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多