首页 > 解决方案 > 使用值和标签动态构建表单控件的方法

问题描述

我刚刚开始使用反应形式。用例是我从 API 获取过滤器,然后像这样动态构建表单控件。构造函数:

constructor(
  private fb: FormBuilder,
) {
  this.typesArray = this.fb.group({});
  this.form = this.fb.group({
    typesArray:  this.typesArray,
  });
}

// a bit further I do this after finishing an API call:
response.forEach((type: any) => {
  (this.form.get('typesArray') as FormGroup).addControl(type.id, new FormControl(false));
});

这会产生一行复选框:

<div *ngFor="let Type of objectKeys(typesArray.controls)">
    <ion-checkbox class="ion-no-margin" type="checkbox" [formControlName]="Type"></ion-checkbox>
    <ion-label class="ion-no-margin" class="ml-2">**HERE I WANT THE LABEL**</ion-label>
</div>

该值由 [formControlName] 绑定,即类型 Id。有没有办法将标签(type.title 例如“Book”、“DVD”)添加到表单控件?

我想避免为了显示正确的标签而必须用我的值和标签建立一个单独的数组。

标签: angularangular-reactive-forms

解决方案


你不需要单独的数组。标题或任何其他字段可以通过原始过滤器数组的索引来解析。

工作样本:

export interface Filter {
    id: number;
    title: string;
    selected: boolean;
}

@Component({
    selector: 'app-demo',
    templateUrl: './demo.component.html',
    styleUrls: ['./demo.component.scss'],
})
export class DemoComponent implements OnInit {

    filters: Filter[] = [{ id: 1, title: 'Book', selected: true }, { id: 2, title: 'DVD', selected: false }];
    form: FormGroup;

    get typesArray(): FormArray {
        return this.form.get('typesArray') as FormArray;
    }

    constructor(private readonly formBuilder: FormBuilder) {}

    ngOnInit(): void {
        this.form = this.formBuilder.group({
            typesArray: new FormArray([]),
        });

        this.filters.forEach((filter) => {
            this.typesArray.push(this.formBuilder.control(filter.selected));
        });

        this.typesArray.valueChanges.subscribe((checkboxValues: boolean[]) => {
            const selectedFilters = checkboxValues
                .map((selected, index) => {
                    return { ...this.filters[index], selected };
                })
                .filter((filters) => filters.selected);

            console.log(selectedFilters);
        });
    }
}
<table>
    <tbody>
    <tr *ngFor="let control of typesArray.controls; let i = index;">
        <td>{{ filters[i].title }}</td>
        <td><input type="checkbox" [formControl]="control"></td>
    </tr>
    </tbody>
</table>

推荐阅读