使用 Angular 的 matAutocomplete,如何显示对象的 属性,但在别处引用对象本身?
Using Angular's matAutocomplete, how do I display an object's property, but reference the object itself elsewhere?
例如我有标记:
<input type="text" class="form-control" placeholder="Project #" name="project" [(ngModel)]="key" (ngModelChange)="filterProjects(key);" matInput [matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="setProject($event.option.value)">
<mat-option *ngFor="let project of filtered" [value]="project.ProjNum">
{{project.ProjNum}}
</mat-option>
</mat-autocomplete>
<div class="input-group-append">
<button class="btn btn-info" (click)="load(selectedProject)">Load</button>
</div>
选择一个选项后,它会调用 setProject()
函数,该函数设置稍后用于我的“加载”按钮的 selectedProject。但是,由于它目前的功能,将值绑定到 [value]="project.ProjNum"
将使用项目编号调用 setProject。虽然将我的值设置为 [value]="project"
似乎很直观(这会将我的 selectedProject
设置为项目对象),但它现在将在我的输入字段中显示 [object Object]
。
如何修改它以便我可以在我的选项之外直接引用 project
对象,而不仅仅是选择和显示的 属性?
注意: 我知道我可以使用 ProjNum 过滤我的项目列表以找到正确的项目,然后设置我的 selectedProject
,但我会当我已经有了我想要的对象时,不要浪费资源循环遍历列表。
您想使用 displayWith
功能。它允许您定义一个函数,该函数 returns 您想要显示的值
来自docs:
<form class="example-form">
<mat-form-field class="example-full-width">
<input type="text" placeholder="Assignee" aria-label="Assignee" matInput [formControl]="myControl" [matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn">
<mat-option *ngFor="let option of filteredOptions | async" [value]="option">
{{option.name}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</form>
import {Component, OnInit} from '@angular/core';
import {FormControl} from '@angular/forms';
import {Observable} from 'rxjs';
import {map, startWith} from 'rxjs/operators';
export interface User {
name: string;
}
/**
* @title Display value autocomplete
*/
@Component({
selector: 'autocomplete-display-example',
templateUrl: 'autocomplete-display-example.html',
styleUrls: ['autocomplete-display-example.css'],
})
export class AutocompleteDisplayExample implements OnInit {
myControl = new FormControl();
options: User[] = [
{name: 'Mary'},
{name: 'Shelley'},
{name: 'Igor'}
];
filteredOptions: Observable<User[]>;
ngOnInit() {
this.filteredOptions = this.myControl.valueChanges
.pipe(
startWith(''),
map(value => typeof value === 'string' ? value : value.name),
map(name => name ? this._filter(name) : this.options.slice())
);
}
displayFn(user?: User): string | undefined {
return user ? user.name : undefined;
}
private _filter(name: string): User[] {
const filterValue = name.toLowerCase();
return this.options.filter(option => option.name.toLowerCase().indexOf(filterValue) === 0);
}
}
例如我有标记:
<input type="text" class="form-control" placeholder="Project #" name="project" [(ngModel)]="key" (ngModelChange)="filterProjects(key);" matInput [matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="setProject($event.option.value)">
<mat-option *ngFor="let project of filtered" [value]="project.ProjNum">
{{project.ProjNum}}
</mat-option>
</mat-autocomplete>
<div class="input-group-append">
<button class="btn btn-info" (click)="load(selectedProject)">Load</button>
</div>
选择一个选项后,它会调用 setProject()
函数,该函数设置稍后用于我的“加载”按钮的 selectedProject。但是,由于它目前的功能,将值绑定到 [value]="project.ProjNum"
将使用项目编号调用 setProject。虽然将我的值设置为 [value]="project"
似乎很直观(这会将我的 selectedProject
设置为项目对象),但它现在将在我的输入字段中显示 [object Object]
。
如何修改它以便我可以在我的选项之外直接引用 project
对象,而不仅仅是选择和显示的 属性?
注意: 我知道我可以使用 ProjNum 过滤我的项目列表以找到正确的项目,然后设置我的 selectedProject
,但我会当我已经有了我想要的对象时,不要浪费资源循环遍历列表。
您想使用 displayWith
功能。它允许您定义一个函数,该函数 returns 您想要显示的值
来自docs:
<form class="example-form">
<mat-form-field class="example-full-width">
<input type="text" placeholder="Assignee" aria-label="Assignee" matInput [formControl]="myControl" [matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn">
<mat-option *ngFor="let option of filteredOptions | async" [value]="option">
{{option.name}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</form>
import {Component, OnInit} from '@angular/core';
import {FormControl} from '@angular/forms';
import {Observable} from 'rxjs';
import {map, startWith} from 'rxjs/operators';
export interface User {
name: string;
}
/**
* @title Display value autocomplete
*/
@Component({
selector: 'autocomplete-display-example',
templateUrl: 'autocomplete-display-example.html',
styleUrls: ['autocomplete-display-example.css'],
})
export class AutocompleteDisplayExample implements OnInit {
myControl = new FormControl();
options: User[] = [
{name: 'Mary'},
{name: 'Shelley'},
{name: 'Igor'}
];
filteredOptions: Observable<User[]>;
ngOnInit() {
this.filteredOptions = this.myControl.valueChanges
.pipe(
startWith(''),
map(value => typeof value === 'string' ? value : value.name),
map(name => name ? this._filter(name) : this.options.slice())
);
}
displayFn(user?: User): string | undefined {
return user ? user.name : undefined;
}
private _filter(name: string): User[] {
const filterValue = name.toLowerCase();
return this.options.filter(option => option.name.toLowerCase().indexOf(filterValue) === 0);
}
}