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
循环之外。
我正在尝试使用 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
循环之外。