FirebaseListObservable<any[]> 作为 material 的列表 2 自动完成不过滤

FirebaseListObservable<any[]> as list for material 2 autocomplete not filtering

我正在尝试使用 angularfire2 并且我想使用 angular material2 自动完成组件。使用我当前的设置,自动完成列表是从 firebase 正确填充的。但是过滤功能似乎不起作用,我不明白为什么。是不是因为我使用的是 switchmap 而不是 map,就像 material 示例正在使用的那样(如果我使用 map,则列表不会被填充并且会抛出错误)? FirebaseListObservable 与普通 Observable 的过滤器功能是否不同?

组件文件

import { Component, OnInit } from '@angular/core';
import { MdDialogRef } from '@angular/material';
import { FormControl } from '@angular/forms';
import { AngularFire, FirebaseListObservable } from 'angularfire2';

@Component({
  selector: 'budget-new-transaction',
  templateUrl: './new-transaction.component.html',
  styleUrls: ['./new-transaction.component.css']
})
export class NewTransactionComponent implements OnInit {
  categories: FirebaseListObservable<any[]>;
  categoryCtrl: FormControl;
  filteredCategories: any;

  constructor(public dialogRef: MdDialogRef<NewTransactionComponent>, public af: AngularFire, ) {
    this.categories = af.database.list('/items');
    this.categoryCtrl = new FormControl();
    this.filteredCategories = this.categoryCtrl.valueChanges
      .startWith(null)
      .switchMap(name => this.filterCategories(name));
  }
  filterCategories(val: string) {
    return val ? this.categories.filter(s => new RegExp(`^${val}`, 'gi').test(s))
      : this.categories;
  }



  ngOnInit() {
  }

}

html 文件

<h3>Add User Dialog</h3>
<form #form="ngForm" (ngSubmit)="dialogRef.close(form.value)" ngNativeValidate>
  <div fxLayout="column" fxLayoutGap="8px">
    <md-input-container>
      <input mdInput placeholder="Category" [mdAutocomplete]="auto" [formControl]="categoryCtrl">
    </md-input-container>
    <md-autocomplete #auto="mdAutocomplete">
      <md-option *ngFor="let category of filteredCategories | async" [value]="category">
        {{ category.$value }}
      </md-option>
    </md-autocomplete>

    <md-input-container>
      <textarea mdInput ngModel name="details" placeholder="Details" rows="15" cols="60" required></textarea>
    </md-input-container>

    <div fxLayout="row" fxLayoutGap="24px">
      <md-checkbox ngModel name="isAdmin">Is Admin?</md-checkbox>
      <md-checkbox ngModel name="isCool">Is Cool?</md-checkbox>
    </div>
  </div>
  <md-dialog-actions align="end">
    <button md-button type="button" (click)="dialogRef.close()">Cancel</button>
    <button md-button color="accent">Save User</button>
  </md-dialog-actions>
</form>

问题是您使用的是 RxJS filter 运算符,而您似乎应该使用 Array.prototype.filter.

this.categories 是一个 FirebaseListObservable,因此它将发出一个包含数据库引用的子项的数组。这意味着您正在将数组传递给正则表达式的 test 方法。

你应该这样做:

import 'rxjs/add/operator/map';

filterCategories(val: string) {
  return val ?
    this.categories.map(list => list.filter(
      s => new RegExp(`^${val}`, 'gi').test(s.$value)
    )) :
    this.categories;
}

此外,您可能希望将 RegExp 的创建移动到隐式 filter 循环之外。