Я работаю над проектом Angluar 7 с Angular-Material и впервые использую реактивные формы. Я реализовал автозаполнение, чтобы пользователь мог выбрать сотрудника из списка EmployeeObjects. Форма использует угловые реактивные формы. Объекты сотрудников намного сложнее, чем пользователь должен знать.
Выбор работника, хранение и обновление формы реагирования работает отлично. Проблема в том, что отображаемое значение в поле ввода выглядит как [объект: объект], поскольку весь объект будет установлен на [значение] поля ввода.
Когда я реализую метод получения, чтобы показать только имя сотрудника, показанное значение выглядит правильно, но значение реактивной формы хранит только отформатированную строку вместо всего объекта.
Как это можно сделать, показать правильную строку пользователю и сохранить все значение в форме?
Спасибо за вашу помощь.
Stackblitz
https://stackblitz.com/edit/angular-autocomplete-employee?file=app%2Fautocomplete-simple-example.html
Класс
@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);
}
}
Template
<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>
Класс сотрудников и список сотрудников
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,
];