如何在所选对象的自动完成中仅显示特定对象属性而不是 Angular 中的 [object] 7
How to show only particular object properties in AutoComplete of selected object instead of [object] in Angular 7
我正在使用 Angular-Material 进行 Angluar 7 项目,并且我是第一次使用响应式表单。我已经实现了自动完成功能,因此用户可以 select EmployeeObjects 列表中的员工。该表单使用 Angular 反应形式。员工的对象比用户需要知道的要复杂得多。
员工的 selection 和反应形式的存储和更新工作正常。问题在于输入字段中显示的值看起来像 [object: object],因为整个对象将设置为输入字段的 [value]。
当我实现 getter 以仅显示员工姓名时,显示的值看起来是正确的,但反应形式值仅存储格式化字符串而不是整个对象。
如何才能做到既向用户显示正确的字符串又将整个值存储在表单中?
感谢您的帮助。
Stackblitz
Class
@Component({
selector: 'app-employee-data',
templateUrl: './employee-data.component.html',
styleUrls: ['./employee-data.component.scss']
})
export class EmployeeDataComponent implements OnInit {
employeeForm: FormGroup;
employeeCtrl = new FormControl();
employees: Employee[] = EmployeeList as Employee[];
filteredEmployees: Observable<Employee[]>;
result;
@Input() employee: Employee;
@ViewChild(MatAutocomplete) matAutocomplete: MatAutocomplete;
constructor(private formBuilder: FormBuilder) {
this.initEmployeeFilters(this.employeeCtrl);
this.employeeForm = this.createFormGroupWithBuilder(formBuilder);
}
ngOnInit() {
}
private _filterStates(value: string): Employee[] {
const filterValue = value.toLowerCase();
return this.employees.filter(employee => employee.lastname.toLowerCase().indexOf(filterValue) === 0);
}
public getFullname(employee: Employee): string {
return employee.lastname + ', ' + employee.firstname;
}
public getEmployee(): Employee {
return JOHN_DOE;
}
private initEmployeeFilters(formCtrl: FormControl) {
this.filteredEmployees = formCtrl.valueChanges
.pipe(
startWith(''),
map(employee => employee ? this._filterStates(employee) : this.employees.slice())
);
}
createFormGroupWithBuilder(formBuilder: FormBuilder) {
return formBuilder.group({
employeeData: formBuilder.group({
employee: new FormControl(),
}),
});
}
revert() {
this.employeeForm.reset();
this.employeeForm.reset({ employeeData: new Employee() });
}
onSubmit() {
this.result = Object.assign({}, this.employeeForm.value);
this.result.employeeData = Object.assign({}, this.result.employeeData);
}
}
模板
<form [formGroup]=„employeeForm" (ngSubmit)="onSubmit()" novalidate>
<div formGroupName="employeeData" novalidate>
<mat-form-field>
<input
matInput
type="text"
placeholder="Name"
[matAutocomplete]="auto"
formControlName="name"
>
<mat-autocomplete #auto="matAutocomplete">
<mat-option
*ngFor="let employee of employees | async"
[value]="getEmployee(employee)"
>
<img
[src]="employee.profilePicture"
height="25"
>
<span>{{employee.lastname}}, {{employee.firstname}}</span>
</mat-option>
</mat-autocomplete>
</mat-form-field>
</div>
<button type="submit" [disabled]="employeeForm.pristine">Save</button>
</form>
员工class和员工名单
export class Employee {
id = 1;
lastname = '';
firstname = '';
}
export const JANE_DOE = {
id: 1,
lastname: 'Doe',
firstname: 'Jane',
profilePicture: ‚url‘
};
export const JOHN_DOE = {
id: 2,
lastname: 'Doe',
firstname: 'John',
profilePicture: ‚url‘
};
export const EmployeeList: Employee[] = [
JANE_DOE,
JOHN_DOE,
];
您可以使用 mat-autocomplete 上的 displayWith
输入来完成此操作。
<mat-autocomplete #auto="matAutocomplete" [displayWith]="valueMapper">
然后在你的组件中
public valueMapper = (key) => {
return key.firstname + ' ' + key.lastname;
};
我正在使用 Angular-Material 进行 Angluar 7 项目,并且我是第一次使用响应式表单。我已经实现了自动完成功能,因此用户可以 select EmployeeObjects 列表中的员工。该表单使用 Angular 反应形式。员工的对象比用户需要知道的要复杂得多。
员工的 selection 和反应形式的存储和更新工作正常。问题在于输入字段中显示的值看起来像 [object: object],因为整个对象将设置为输入字段的 [value]。
当我实现 getter 以仅显示员工姓名时,显示的值看起来是正确的,但反应形式值仅存储格式化字符串而不是整个对象。
如何才能做到既向用户显示正确的字符串又将整个值存储在表单中?
感谢您的帮助。
Stackblitz
Class
@Component({
selector: 'app-employee-data',
templateUrl: './employee-data.component.html',
styleUrls: ['./employee-data.component.scss']
})
export class EmployeeDataComponent implements OnInit {
employeeForm: FormGroup;
employeeCtrl = new FormControl();
employees: Employee[] = EmployeeList as Employee[];
filteredEmployees: Observable<Employee[]>;
result;
@Input() employee: Employee;
@ViewChild(MatAutocomplete) matAutocomplete: MatAutocomplete;
constructor(private formBuilder: FormBuilder) {
this.initEmployeeFilters(this.employeeCtrl);
this.employeeForm = this.createFormGroupWithBuilder(formBuilder);
}
ngOnInit() {
}
private _filterStates(value: string): Employee[] {
const filterValue = value.toLowerCase();
return this.employees.filter(employee => employee.lastname.toLowerCase().indexOf(filterValue) === 0);
}
public getFullname(employee: Employee): string {
return employee.lastname + ', ' + employee.firstname;
}
public getEmployee(): Employee {
return JOHN_DOE;
}
private initEmployeeFilters(formCtrl: FormControl) {
this.filteredEmployees = formCtrl.valueChanges
.pipe(
startWith(''),
map(employee => employee ? this._filterStates(employee) : this.employees.slice())
);
}
createFormGroupWithBuilder(formBuilder: FormBuilder) {
return formBuilder.group({
employeeData: formBuilder.group({
employee: new FormControl(),
}),
});
}
revert() {
this.employeeForm.reset();
this.employeeForm.reset({ employeeData: new Employee() });
}
onSubmit() {
this.result = Object.assign({}, this.employeeForm.value);
this.result.employeeData = Object.assign({}, this.result.employeeData);
}
}
模板
<form [formGroup]=„employeeForm" (ngSubmit)="onSubmit()" novalidate>
<div formGroupName="employeeData" novalidate>
<mat-form-field>
<input
matInput
type="text"
placeholder="Name"
[matAutocomplete]="auto"
formControlName="name"
>
<mat-autocomplete #auto="matAutocomplete">
<mat-option
*ngFor="let employee of employees | async"
[value]="getEmployee(employee)"
>
<img
[src]="employee.profilePicture"
height="25"
>
<span>{{employee.lastname}}, {{employee.firstname}}</span>
</mat-option>
</mat-autocomplete>
</mat-form-field>
</div>
<button type="submit" [disabled]="employeeForm.pristine">Save</button>
</form>
员工class和员工名单
export class Employee {
id = 1;
lastname = '';
firstname = '';
}
export const JANE_DOE = {
id: 1,
lastname: 'Doe',
firstname: 'Jane',
profilePicture: ‚url‘
};
export const JOHN_DOE = {
id: 2,
lastname: 'Doe',
firstname: 'John',
profilePicture: ‚url‘
};
export const EmployeeList: Employee[] = [
JANE_DOE,
JOHN_DOE,
];
您可以使用 mat-autocomplete 上的 displayWith
输入来完成此操作。
<mat-autocomplete #auto="matAutocomplete" [displayWith]="valueMapper">
然后在你的组件中
public valueMapper = (key) => {
return key.firstname + ' ' + key.lastname;
};