Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/26.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
Angular 如何从google firestore中筛选可观察对象_Angular_Observable - Fatal编程技术网

Angular 如何从google firestore中筛选可观察对象

Angular 如何从google firestore中筛选可观察对象,angular,observable,Angular,Observable,我正在使用来自firestore的observable来填充选择列表 getInvoices() { this.invCollection = this.afs.collection('invoices'); this.invoices = this.invCollection.snapshotChanges().pipe( shareReplay(1), map(actions => { return actions.map(action => ({ key:

我正在使用来自firestore的observable来填充选择列表

getInvoices() {
this.invCollection = this.afs.collection('invoices');
this.invoices = this.invCollection.snapshotChanges().pipe(
  shareReplay(1),
  map(actions => {
  return actions.map(action => ({
    key: action.payload.doc.id,
    ...action.payload.doc.data()
  }))
})
)

this.invList = this.invoices.source;
}

我将这个.inv observable中的数据与这个.invList observable共享

我想根据用户选择过滤第二个可观察的

<mat-form-field class="ffield">
    <mat-select (selectionChange)="getInv($event)" placeholder="Choose invoice">
      <mat-option *ngFor="let invoice of invoices | async; trackBy: trackByFn" [value]="invoice.key">{{invoice.invNo}}</mat-option>
    </mat-select>
  </mat-form-field>


getInv(e) {
  this.sID = e.value; //id of selected invoice

  //TODO filter this.invList observable   }
但它不起作用,属性键不存在流中的

rxjs筛选器运算符筛选器值您的数组是流中的单个值,在您的情况下,您不需要流中的筛选器值,您需要按ID将值数组映射到特定值

this.invoices$ = this.invCollection.snapshotChanges().pipe(
  map(actions => 
    actions.map(action => 
      ({
        key: action.payload.doc.id,
        ...action.payload.doc.data()
      })
    )
  )
)
如果您需要使用特定id的元素创建流:

getInvoiseById(id): Observable<InvoiceType> {
 return this.invoices$.pipe(
   map(invoices => 
     invoices.filter(({key}) => key === id)))
   )
}
若您需要使用活动发票创建流,更好的方法是使用活动ID创建流,并将其与发票流相结合

activeId$ = new Subject<TypeOfIdField>();

activeInvoice$ = combineLatest([
  this.invoices$,
  this.activeId$
]).pipe(
  map(([invoices, id]) => 
    invoices.find(({key}) => key === id)
  )
)

setActiveId(id) {
  this.activeId$.next(id);
}


注意:如果您想使用shareReplay,最好将其移动到管道的末尾,在代码中首先缓存初始数据,然后将其映射到使用的格式,在这种情况下,如果您将shareReplay移动到管道的末尾,您将转换每个子描述的数据,您缓存了已转换的数据

这里的flt是什么?谢谢您的回答。在阅读您的答案时,我的第一个想法是这是如此明显和合乎逻辑,但后来我尝试使用getInvoiseByIdid函数,但这不起作用,我不明白为什么。我应该如何使用函数GetInvoiseById这是一个不错的选择如果你的ID是静态的,那么你可以用ID过滤的元素创建流,你可以用异步管道或者任何你想要的东西来使用它。你可以描述你的需求用例吗?我正在使用Firestore中的Observable来填充选择列表,-this.invoices。我已经在使用异步管道了。选择列表附带有库存id和库存编号。当用户选择其中一张发票时,下面的文本字段应填写相应的数据。所以我想按库存id筛选可观察的发票,因为它包含我需要的所有数据并填写表单字段。最好使用CombineTest和activeId$stream,它允许您在单个流中获取活动发票。如果使用getInvoiseById,则为每个ID创建新流
activeId$ = new Subject<TypeOfIdField>();

activeInvoice$ = combineLatest([
  this.invoices$,
  this.activeId$
]).pipe(
  map(([invoices, id]) => 
    invoices.find(({key}) => key === id)
  )
)

setActiveId(id) {
  this.activeId$.next(id);
}