Angular FormGroup 没有收到来自子 FormGroup 的更改
Angular FormGroup receives no changes from child FormGroup
我有一个反应式 Angular 11 表单,它根据选择动态构建额外的控件。这些控件都添加在父窗体的同一个 FormGroup 中,并且是必需的,但即使我填写每个字段,父窗体仍然无效。
模板如下所示:
<form [formGroup]="emailForm" (ngSubmit)="onSubmit()">
<div class="template">
<label for="template">Template</label>
<select formControlName="template" id="template" required>
<option *ngFor="let template of templateNames" value="{{template}}">{{template}}</option>
</select>
</div>
<div class="language">
<label for="language">Language</label>
<select formControlName="language" id="language" required>
<option *ngFor="let language of templateLanguages" value="{{language}}">{{language}}</option>
</select>
</div>
<div class="placeholders" formGroupName="placeholders">
<p>Placeholders</p>
<div *ngFor="let placeholder of templatePlaceholders" class="placeholders__placeholder">
<label for="{{placeholder}}-field">{{placeholder}}</label>
<input id="{{placeholder}}-field" required type="text">
</div>
</div>
<div class="submit">
<input type="submit" value="Send" [disabled]="!emailForm.valid">
</div>
</form>
这是组件(剥离了大部分行为以保持示例最小和可重现):
public emailForm!: FormGroup;
public templateNames = ["one", "two", "three"];
public templateLanguages = ["en", "pt", "de"];
public templatePlaceholders: string[] = [];
ngOnInit(): void {
this.emailForm = new FormGroup({
template: new FormControl(),
language: new FormControl(),
placeholders: new FormGroup({}),
}, Validators.required);
this.populatePlaceholders();
}
populatePlaceholders(): void {
const placeholders: string[] = [];
// Some API call...
// ...
const placeholderFields: Record<string, FormControl> = {};
placeholders.forEach((placeholder) => {
placeholderFields[placeholder] = new FormControl("", Validators.required);
this.templatePlaceholders.push(placeholder);
});
this.emailForm.setControl("placeholders", new FormGroup(placeholderFields));
}
问题是,即使我填写了每个字段,即使根本没有占位符字段,提交按钮仍处于禁用状态。我已经尝试在 valueChanges
上记录 emailForm.placoholders
的状态,我可以看到它保持不变(如果我在字段中输入任何内容,该值不会显示在其控件中),并且 valueChanges
如果我在子字段中输入任何内容,甚至不会触发事件,只有当它在第一级控件之一时才会触发。
我对 Angular 很陌生,所以我一定是做错了什么,但是什么?
编辑: 代码的堆栈闪电战:
https://stackblitz.com/edit/angular-ivy-mdzjn8?file=src/app/app.component.ts
我发现了问题:我忘记将 formControlName
属性添加到模板中的控件。我加了formControlName="{{placeholder}}"
,问题解决了
我希望像这样容易忘记的事情有一个明确的错误;真的很难调试。
我有一个反应式 Angular 11 表单,它根据选择动态构建额外的控件。这些控件都添加在父窗体的同一个 FormGroup 中,并且是必需的,但即使我填写每个字段,父窗体仍然无效。
模板如下所示:
<form [formGroup]="emailForm" (ngSubmit)="onSubmit()">
<div class="template">
<label for="template">Template</label>
<select formControlName="template" id="template" required>
<option *ngFor="let template of templateNames" value="{{template}}">{{template}}</option>
</select>
</div>
<div class="language">
<label for="language">Language</label>
<select formControlName="language" id="language" required>
<option *ngFor="let language of templateLanguages" value="{{language}}">{{language}}</option>
</select>
</div>
<div class="placeholders" formGroupName="placeholders">
<p>Placeholders</p>
<div *ngFor="let placeholder of templatePlaceholders" class="placeholders__placeholder">
<label for="{{placeholder}}-field">{{placeholder}}</label>
<input id="{{placeholder}}-field" required type="text">
</div>
</div>
<div class="submit">
<input type="submit" value="Send" [disabled]="!emailForm.valid">
</div>
</form>
这是组件(剥离了大部分行为以保持示例最小和可重现):
public emailForm!: FormGroup;
public templateNames = ["one", "two", "three"];
public templateLanguages = ["en", "pt", "de"];
public templatePlaceholders: string[] = [];
ngOnInit(): void {
this.emailForm = new FormGroup({
template: new FormControl(),
language: new FormControl(),
placeholders: new FormGroup({}),
}, Validators.required);
this.populatePlaceholders();
}
populatePlaceholders(): void {
const placeholders: string[] = [];
// Some API call...
// ...
const placeholderFields: Record<string, FormControl> = {};
placeholders.forEach((placeholder) => {
placeholderFields[placeholder] = new FormControl("", Validators.required);
this.templatePlaceholders.push(placeholder);
});
this.emailForm.setControl("placeholders", new FormGroup(placeholderFields));
}
问题是,即使我填写了每个字段,即使根本没有占位符字段,提交按钮仍处于禁用状态。我已经尝试在 valueChanges
上记录 emailForm.placoholders
的状态,我可以看到它保持不变(如果我在字段中输入任何内容,该值不会显示在其控件中),并且 valueChanges
如果我在子字段中输入任何内容,甚至不会触发事件,只有当它在第一级控件之一时才会触发。
我对 Angular 很陌生,所以我一定是做错了什么,但是什么?
编辑: 代码的堆栈闪电战: https://stackblitz.com/edit/angular-ivy-mdzjn8?file=src/app/app.component.ts
我发现了问题:我忘记将 formControlName
属性添加到模板中的控件。我加了formControlName="{{placeholder}}"
,问题解决了
我希望像这样容易忘记的事情有一个明确的错误;真的很难调试。