如何在所选对象的自动完成中仅显示特定对象属性而不是 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

https://stackblitz.com/edit/angular-autocomplete-employee?file=app%2Fautocomplete-simple-example.html

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;
};