FirebaseListObservable <any []>作为材料2自动完成而非过滤的列表

时间:2017-04-12 18:57:33

标签: angularfire2 angular-material2 angular2-observables

我正在尝试使用angularfire2,我想使用angular material2自动完成组件。使用我当前的设置,自动完成列表从firebase正确填充。但是过滤功能似乎不起作用,我无法弄清楚原因。是因为我使用switchmap而不是像材质示例使用的地图(如果我使用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>

1 个答案:

答案 0 :(得分:1)

问题是当您看起来应该使用filter时,您正在使用RxJS Array.prototype.filter运算符。

this.categoriesFirebaseListObservable,因此会发出一个数组,用于表示数据库引用的子项。这意味着您将数组传递给正则表达式的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循环之外。