我正在尝试使用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>
答案 0 :(得分:1)
问题是当您看起来应该使用filter
时,您正在使用RxJS 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
循环之外。