Angular Reactive Form - 使用对象而不是值修补表单控件时出现问题

问题描述 投票:0回答:2

我在 Angular 表单中使用

mat-select
来让用户选择多个国家/地区作为具有
id
name
属性的对象。但是,我需要使用完整的国家/地区对象(而不仅仅是其 ID)来修补表单控件,但它的行为并不符合预期。这是相关的代码片段!!!

我需要使用完整的国家/地区对象而不是 ID 来修补表单控件,但目前,它仅适用于国家/地区 ID。

<form [formGroup]="countryForm" (ngSubmit)="onSubmit()">
    <mat-form-field appearance="outline">
      <mat-label>Countries</mat-label>
      <mat-select formControlName="countryControl" multiple >
          <mat-option *ngFor="let country of countries" [value]="country">
              {{ country.name }}
          </mat-option>
      </mat-select>

  </mat-form-field>

  </form>
  <div>
    <button mat-raised-button color="accent" type="button" (click)="patchFormWithCountry()">Patch Form</button>
  </div>

这是我的ts:

import { Component } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';

/** @title Form field appearance variants */
@Component({
  selector: 'form-field-appearance-example',
  templateUrl: 'form-field-appearance-example.html',
})
export class FormFieldAppearanceExample {
  countryForm: FormGroup;
  countries: any[] = [
    { id: 1, name: 'United States' },
    { id: 2, name: 'Canada' },
    { id: 3, name: 'United Kingdom' },
    { id: 4, name: 'Australia' },
    { id: 5, name: 'Germany' },
    { id: 6, name: 'France' },
    { id: 7, name: 'Italy' },
    { id: 8, name: 'Spain' },
    { id: 9, name: 'India' },
    { id: 10, name: 'China' },
    { id: 11, name: 'Japan' },
    { id: 12, name: 'Brazil' },
    { id: 13, name: 'South Africa' },
    { id: 14, name: 'Mexico' },
    { id: 15, name: 'Russia' },
  ];

  constructor(private fb: FormBuilder) {}

  ngOnInit() {
    this.countryForm = this.fb.group({
      countryControl: [''],
    });
  }

  patchFormWithCountry() {
    const selectedCountries = [
      { id: 1, name: 'United States' },
      { id: 2, name: 'Canada' },
      { id: 3, name: 'United Kingdom' },
      { id: 4, name: 'Australia' },
    ];

    this.countryForm.patchValue({
      countryControl: selectedCountries,
    });
  }

  onSubmit() {
    console.log('Form submitted:', this.countryForm.value);
  }
}
angular forms angular-material angular-reactive-forms mat-select
2个回答
1
投票

您需要实现

compareWith
函数,以便当该值是复杂值(例如对象)时可以映射/修补
<mat-select>
选项。

参考:获取和设置选择值

<mat-select
  formControlName="countryControl"
  multiple
  [compareWith]="countryCompareWithFn"
>
  <mat-option *ngFor="let country of countries" [value]="country">
    {{ country.name }}
  </mat-option>
</mat-select>
countryCompareWithFn = (country: any, value: any) => country.id == value.id;

演示@StackBlitz


1
投票

您必须导入

CommonModule
才能使
ngFor
正常工作。

其次,您必须确保使用相同的内存引用,因为对象和数组在内存中存储为引用。所以我过滤了这些国家的原始数组,这里我使用数组方法

filter
,它根据条件过滤掉值。我使用数组方法
includes
来检查该值是否存在于数组中。

国家/地区控制表单,不应初始化为字符串,它应该只是一个空数组。

this.countryForm = this.fb.group({
  countryControl: [],
});

片段:

patchFormWithCountry() {
  const toFilter = [
    'United States',
    'Canada',
    'United Kingdom',
    'Australia',
  ];
  const selectedCountries = this.countries.filter((item: any) => toFilter.includes(item.name))

  this.countryForm.patchValue({
    countryControl: selectedCountries,
  });
}

Stackblitz 演示

© www.soinside.com 2019 - 2024. All rights reserved.