我有一个实体
CarrierFilterOption
:
export interface CarrierFilterOption {
label: string;
isChecked: boolean;
}
反应形式定义为:
plansService = inject(PlansService);
planListForm = this.formBuilder.group({
carrierFilterOptions: this.formBuilder.array<CarrierFilterOption>([])
});
我需要使用通过 HTTP API 调用从plansService 加载并表示为信号的值来填充
carrierFilterOptions
:
@Injectable({ providedIn: 'root' })
export class PlansService {
public filterOptions = signal<CarrierFilterOption[]>([]);
constructor() {
// filterOptions are populated from HTTP call to API
}
}
当我使用类似的东西时
this.planListForm.controls.carrierFilterOptions.setValue(this.plansService.filterOptions());
在
ngOnInit
我正在
ERROR Error: NG01000:
There are no form controls registered with this array yet. If you're using ngModel,
you may want to check next tick (e.g. use setTimeout).
如何最好地做到这一点?或者信号对于这种情况来说不是一个好主意?
由于您尚未共享正在使用的数据对象,因此我们需要订阅组件上的数据,因为表单值将在获取表单数据后立即设置,这是遗漏的部分,我们需要循环遍历数据并为每一行创建
FormGroup/FormControl
并将其推送到 FormArray
(CarrierFilterOptions),然后最后为每个控件运行 *ngFor
并将它们呈现在表单上!由于我没有数据,我创建了一个模拟形式,希望它能帮助您!
ts
import { CommonModule } from '@angular/common';
import { Component, inject } from '@angular/core';
import {
FormArray,
FormBuilder,
FormControl,
FormGroup,
ReactiveFormsModule,
} from '@angular/forms';
import { bootstrapApplication } from '@angular/platform-browser';
import 'zone.js';
import { PlansService } from './plans.service';
export interface CarrierFilterOption {
label: string;
isChecked: boolean;
}
@Component({
selector: 'app-root',
standalone: true,
imports: [ReactiveFormsModule, CommonModule],
template: `
<form [formGroup]="planListForm">
<div formArrayName="carrierFilterOptions">
<ng-container *ngFor="let control of carrierFilterOptions.controls; let i = index">
<div [formGroupName]="i" *ngIf="filterOptions()[i].label as label">
<input type="checkbox" [formControlName]="label" [id]="label" [name]="label"/>
<label [for]="label">{{label}}</label>
</div>
</ng-container>
</div>
</form>
{{planListForm.value | json}}
`,
})
export class App {
plansService = inject(PlansService);
planListForm = this.formBuilder.group({
carrierFilterOptions: this.formBuilder.array<CarrierFilterOption>([]),
});
get carrierFilterOptions(): FormArray {
return this.planListForm.get('carrierFilterOptions') as FormArray;
}
constructor(private formBuilder: FormBuilder) {}
get filterOptions() {
return this.plansService.filterOptions;
}
ngOnInit() {
this.plansService.getPlans().subscribe((data: CarrierFilterOption[]) => {
this.plansService.filterOptions.set(data);
this.plansService.filterOptions().forEach((filter) => {
this.carrierFilterOptions.push(
new FormGroup({
[filter.label]: new FormControl(filter.isChecked),
})
);
});
});
}
}
bootstrapApplication(App);