当前位置:  开发笔记 > 编程语言 > 正文

Firebase Angular2 - 如何在没有太多开销的情况下查询和呈现列表

如何解决《FirebaseAngular2-如何在没有太多开销的情况下查询和呈现列表》经验,为你挑选了1个好方法。

在我的应用程序中,我有以下firebase帖子结构:

posts: {
    text: ".."
    meta: {..}
    user: {
        id: "user1",
        username: ".."
    }
}

我正在使用angularfire2.因此,要获取特定用户发布的所有帖子,我运行以下查询:

this.userPosts$ = this.af.database.list('/posts', {
    query: {
      orderByChild: 'user/id',
      equalTo: userId
    }
  }).map( (posts) => {
    return posts.map(post => Post.unpack(post));
  }).publishReplay(1).refCount();

我听说它效率不高,因为每次有变化(即使在一个帖子中),整个列表都会被重新加载,从而重新渲染.由于我在我的应用程序中有喜欢和不喜欢,这将经常发生.基本上每当有人喜欢帖子时,如果我没有弄错的话,每个用户都会重新加载整个列表.

我知道有一种方法可以在监听firebase事件时维护列表的本地副本:"child_added","child_removed"和"child_changed".但是,如果我将这些事件附加到查询列表中,则每次原始帖子列表中的某些内容发生更改时,它们都会触发.

所以,我在想这里采取什么方法.我可能会将帖子数据复制到firebase中的"user_posts"列表中,如果它是唯一的好选择.然而,通过这种方法,我觉得查询变得几乎无用,我失去了灵活性.大约一个星期前我开始使用firebase,所以我可能仍会有一些误解.



1> cartant..:

当寻找到这个问题,我发现了一个问题与FirebaseListObservable实现时preserveSnapshotfalse-默认行为.每次observable发出一个未包装的快照数组时,数组元素都是不同的实例 - 即使元素本身没有改变.这导致变化检测效率低得多.

一个修补程序已被合并,并会被列入AngularFire2的下一个版本(也就是后面的版本2.0.0-beta.7) -它应该很快.

通过修复,如果使用Angular的OnPush变化检测,AngularFire2 FirebaseListObservable在DOM更新方面非常快速有效.

我通常将组件分成容器和表示组件,容器组件使用OnPush变化检测来保持可观察和表示组件.

容器组件看起来像这样:

import { Component } from "@angular/core";
import { AngularFire, FirebaseListObservable } from "angularfire2";

@Component({
  selector: "items-container",
  template: ``
})
export class ItemsContainer {

  private items: FirebaseListObservable;

  constructor(private angularFire: AngularFire) {
    this.items = angularFire.database.list("some/fast-changing/data", {
      query: {
        limitToLast: 1000
      }
    });
  }
}

表示组件看起来像这样:

import { ChangeDetectionStrategy, Component, Input } from "@angular/core";

@Component({
  changeDetection: ChangeDetectionStrategy.OnPush,
  selector: "items-component",
  template: `
    
  • {{ item | json }}
` }) export class ItemsComponent { @Input() items: any[]; }

通过这种组件排列,Angular的OnPush更改检测将确保只有实际更改的元素才会影响DOM更新.因此,即使很长时间,滚动列表也会高效而快速.

另一个提示:FirebaseListObserable当底层数据发生变化时,使用限制查询的a有时会发出两个值.例如,当一个新项目添加到数据库时,查询最近10个项目(使用limitToLast: 10)的列表将发出一个删除了最近项目的数组,然后立即发出另一个项目并添加最新项目.如果您不希望发出这两个数组中的第一个,则可以使用auditTime运算符:

import "rxjs/add/operator/auditTime";

this.items = angularFire.database.list("some/fast-changing/data", {
  query: {
    limitToLast: 10
  }
})
.auditTime(0);

推荐阅读
360691894_8a5c48
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有