AngularFire2检索don';t订阅更改(Firestore)
在我的网站中,我想按项目名称显示项目列表。可以单击名称,然后下载整个文档,您可以编辑和保存项目 目前,我正在使用文档中描述的方式从FireStore查询收集数据:AngularFire2检索don';t订阅更改(Firestore),angular,angularfire2,Angular,Angularfire2,在我的网站中,我想按项目名称显示项目列表。可以单击名称,然后下载整个文档,您可以编辑和保存项目 目前,我正在使用文档中描述的方式从FireStore查询收集数据: 私有项目集合:AngularFirestoreCollection; 项目:可观察; 建造商(私人afs:AngularFirestore){ this.itemsCollection=afs.collection('items'); this.items=this.itemsCollection.valueChanges(); }
私有项目集合:AngularFirestoreCollection;
项目:可观察;
建造商(私人afs:AngularFirestore){
this.itemsCollection=afs.collection('items');
this.items=this.itemsCollection.valueChanges();
}
问题是,我确实不想或不需要对我的列表进行实时更新。因此,可观察的方法对我的应用程序来说真的没有意义
我想到的唯一方法就是使用snapshotChanges方法,将其映射到一个数组,然后将其分配给一个字段。在映射函数之后,将items和itemsCollection字段设置为null,这样它们就不会浪费更多的带宽。但我觉得这不太对
有没有一种方法可以在AngularFire中只查询一次集合(最好是使用查询参数),然后显示它?我处理这个问题的一种方法是使用
rxjs/add/operator/first
。此方法在订阅结束后获取可观察数据
只需导入上面的库并按如下方式进行调用:
this.items=this.itemsCollection.valueChanges().first()代码>
然后您可以订阅它,它将只获取一次数据:
this.items.subscribe((items)=>{
//使用items数组执行某些操作//
});代码>
我知道还有其他方法可以使用rxjsdo()
和take()
方法来处理这个问题,因为您可能需要研究这些方法。我希望这能有所帮助 如果您愿意,可以使用标准的Firebase SDK for the Web,它提供了基于promiss的API(请查看文档),这样您就可以在服务中创建Promise类型的getter(或Observable.fromPromise(),该getter只能执行一次):
从“firebase”导入*作为firebase;
const itemsRef=firebase.firestore().collection('items');
//为您服务:
getItems():承诺{
常数项:项[];
returnitemsref.get()
.then(colSnap=>colSnap.docs().map(snapshot=>snapshot.data());
}
正如Nicholas Pesa已经回答的那样,使用.first()操作符可以工作,唯一需要注意的是它在发出值后不会取消订阅。如果使用.take(整数)运算符作为.take(1),则可观察对象将在发出第一个值后完成。
这是不正确的。
下面关于可观测值的注释是有效的
通过这种方式,你实际上让事情变得更加困难,几乎没有任何好处。可观察的方法使事情变得更容易,即使您不会真正使用可观察的流方法。只需让异步管道(|)为您处理订阅,这样您就不必担心订阅或取消订阅。如果您的数据没有更改,那么模板将只在第一次调用firestore中的该集合。可能有一些有用的东西:您可以链接到一个源,以声明first()
不会从其源取消订阅吗?我的理解一直是first()
和take(1)
在很大程度上是等效的。
private itemsCollection: AngularFirestoreCollection<Item>;
items: Observable<Item[]>;
constructor(private afs: AngularFirestore) {
this.itemsCollection = afs.collection<Item>('items');
this.items = this.itemsCollection.valueChanges();
}
import * as firebase from 'firebase';
const itemsRef = firebase.firestore().collection('items');
// Into your service:
getItems(): Promise<Item[]> {
const items: Item[];
return itemsRef.get()
.then(colSnap => colSnap.docs().map(snapshot => snapshot.data()));
}