我想将物料自动完成组件创建为可重用组件。我正在通过[item]="stations"
将对象传递给父级到子级。过滤不起作用。这是预期的行为material autocomplete。谁能告诉我我在哪里犯错了?
app-autocomplete.ts
export class MatFilterDownloadComponent implements OnInit, ControlValueAccessor {
@Input()
items: any[];
constructor() {}
myControl = new FormControl();
filteredOptions: Observable<any[]>;
private _backup: IComboBoxItem;
private _value: IComboBoxItem;
private _onChangeCallback: (_: any) => {};
get value(): any {
return this._value ? this._value.text : '';
}
@Input()
set value(value: any) {
console.log('value', value);
if (!value) {
return;
}
if (this._value && this._value.text === value) {
return;
}
const items = this.items || [];
const found = items.find((s) => s.text === value);
console.log('found', found);
if (!found) {
return;
}
this._value = found;
this._onChangeCallback(found);
}
ngOnInit() {
this.filteredOptions = this.myControl.valueChanges.pipe(
startWith(''),
map((value) => (typeof value === 'string' ? value : value.value)),
map((name) => (name ? this._filter(name) : this.items.slice())),
);
}
displayFn(user?: any): string | undefined {
console.log('user', user);
return user ? user.text : undefined;
}
private _filter(name: string): any[] {
const filterValue = name.toLowerCase();
return this.items.filter((option) => option.text.toLowerCase().indexOf(filterValue) === 0);
}
writeValue(value: any) {
this._value = value;
}
registerOnChange(fn: any) {
this._onChangeCallback = fn;
}
registerOnTouched() {}
clearInput() {
this._backup = this._value;
this._value = null;
}
undoInput() {
this._value = this._backup;
}
}
app-autocomplete.html
<div class="mat-filter-download-wrapper">
<div class="mat-filter-download-wrapper__search">
<mat-form-field appearance="outline" class="mat-filter-download-wrapper--search-input">
<mat-label>Search</mat-label>
<input type="text" placeholder="Pick one" matInput [(ngModel)]="value" [formControl]="myControl" [matAutocomplete]="auto" />
<mat-autocomplete #auto="matAutocomplete" #auto="matAutocomplete" [displayWith]="displayFn">
<mat-option *ngFor="let station of filteredOptions | async" [value]="station.text">
{{ station.text }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</div>
app.ts
export class AppComponent implements OnInit {
ngOnInit() {
this.indexStations();
}
indexStations() {
this.orderService
.indexStationsLite()
.pipe(
takeUntil(this.allSub),
map((items) =>
items.map(
(station) =>
({
text: this.titleCasePipe.transform(station.name),
value: station.id,
} as IDropdownItem),
),
),
)
.subscribe((stations) => {
this.stations = stations;
});
}
}
app.html
<app-mat-filter-download
[(ngModel)]="filterValues"
[items]="stations"
(ngModelChange)="filter()"
></app-mat-filter-download>
sample.json
[
{
"text":"station1",
"value":"100"
},
{
"text":"station2",
"value":"200"
},
{
"text":"station3",
"value":"300"
}
]