如何从Google Firestore过滤可观察到的

时间:2019-05-18 23:24:21

标签: angular observable

我正在使用从Firestore观察到的内容来填充选择列表

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;

}

我与this.invList observable共享this.inv中的数据

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

<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   }

我需要过滤this.invList可观察的帮助

我确实尝试过类似

this.invList.pipe(map(aaa => {return aaa.map(bbb => ())}), filter(flt => flt.key === this.sID)).subscribe(sss => (console.log(sss.invNo)))

但不起作用,属性键不存在

1 个答案:

答案 0 :(得分:1)

rxjs filter运算符在流中过滤值(您的数组是流中的单个值),如果您不需要流中的过滤值,则需要map个值数组来通过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移动到管道的末尾,则将缓存已转换的数据