Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/32.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
AngularFire2检索don';t订阅更改(Firestore)_Angular_Angularfire2 - Fatal编程技术网

AngularFire2检索don';t订阅更改(Firestore)

AngularFire2检索don';t订阅更改(Firestore),angular,angularfire2,Angular,Angularfire2,在我的网站中,我想按项目名称显示项目列表。可以单击名称,然后下载整个文档,您可以编辑和保存项目 目前,我正在使用文档中描述的方式从FireStore查询收集数据: 私有项目集合:AngularFirestoreCollection; 项目:可观察; 建造商(私人afs:AngularFirestore){ this.itemsCollection=afs.collection('items'); this.items=this.itemsCollection.valueChanges(); }

在我的网站中,我想按项目名称显示项目列表。可以单击名称,然后下载整个文档,您可以编辑和保存项目

目前,我正在使用文档中描述的方式从FireStore查询收集数据:

私有项目集合: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数组执行某些操作//
});


我知道还有其他方法可以使用rxjs
do()
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()));
}