FormGroup
を定義するAngularコンポーネントがあり、そのコントロールの1つとしてネストされたFormGroup
があります。
子FormGroup
は@Input
パラメーターとして子に渡されますcomponent、子FormGroup
内のいくつかのコントロールにバリデーターがあります。
何らかの理由で、parentvalid
のFormGroup
プロパティは、子コンポーネントの値を更新した後でのみ更新され、次に親FormGroup
の入力の1つにランダムな変更を加えます(にスペースを追加するなど)入力)。
セットアップはかなり複雑です(特定の条件に応じて、child FormGroupのコントロールにバリデーターが追加または削除されます。これが、検証が自動的に行われない理由である可能性があります)。
子FormGroup
の何かが変更されたらすぐに、親FormGroup
を手動でトリガーして再検証するにはどうすればよいですか? childコンポーネントでこれを試しました:
ngOnInit()
this.myForm.valueChanges.subscribe(val => {
this.myForm.updateValueAndValidity({onlySelf: false, emitEvent: true})
});
これは、入力のいずれかが変更されるたびにchild
FormGroupの再検証をトリガーし、イベントをparent
コンポーネントにブロードキャストすることになっています。これにより、親FormGroup
の再検証がトリガーされます。ただし、これにより無限ループが発生するため、ある種のスタックオーバーフローエラーが発生します。
親FormGroup
をトリガーして自動的に再検証するにはどうすればよいですか?
this.FormGroup.updateValueAndValidity();
updateValueAndValidity()-これはFormGroupを使用したデフォルトのメソッドです
私はこのようなことをしました、例えばそれは私の子フォームグループです:
私の子フォームグループコンポーネント:
import { Component, Input } from "@angular/core";
import { FormGroup } from "@angular/forms";
@Component({
selector: 'input-form-control',
templateUrl: './input-form-control.component.html'
})
export class InputFormControlComponent {
public formGroup: FormGroup;
@Input('label') formControlLabel: string;
@Input('controlId') formControlId: string;
@Input('name') formControlName: string;
@Input('type') formControlType: string;
@Input('errorText') formControlErrorText: string;
@Input('helpText') formControlHelpText: string;
@Input('group')
set formControl(group) {
this.formGroup = group;
}
@Input('required') isRequired: boolean;
@Input('value')
set value(value: string) {
this.currentValue = value;
this.store({ value });
this.setAsTouched();
}
}
get value(): string {
return this.currentValue;
}
@Output('valueChange') valueChange: EventEmitter<any> = new EventEmitter();
setAsTouched() {
this.formGroup.controls[this.formControlName].markAsTouched();
}
store(data) {
if (!this.formGroup.controls[this.formControlName]) {
return;
}
if (data.value === EMPTY_ITEM) {
this.formGroup.controls[this.formControlName].setValue('');
this.valueChange.emit({ value: '' });
return;
}
this.formGroup.controls[this.formControlName].setValue(data.value);
this.valueChange.emit(data);
}
}
それはテンプレートです:
<form [formGroup]="formGroup" class="m-form m-form--fit">
<div class="form-group m-form__group row" [ngClass]="{
'has-danger': formGroup.controls[formControlName].invalid && formGroup.controls[formControlName].touched,
'has-success': formGroup.controls[formControlName].valid && formGroup.controls[formControlName].touched,
'has-no-action': formGroup.controls[formControlName].untouched
}">
<label class="col-form-label col-lg-3 col-sm-12" [for]="formControlId">
{{formControlLabel}}
<span *ngIf="isRequired" class="required" aria-required="true"> * </span>
</label>
<div class="col-lg-4 col-md-9 col-sm-12">
<input [type]="formControlType || 'text'" class="form-control m-input" [formControlName]="formControlName" [name]="formControlName" [id]="formControlId" [placeholder]="formControlLabel" (click)="setAsTouched()" (valueChanged)="store($event)">
<div class="form-control-feedback">{{formControlErrorText || 'Required Field May Not Be Empty'}}</div>
<span class="m-form__help">{{formControlHelpText}}</span>
</div>
</div>
<div class="form-group m-form__group"></div>
</form>
親テンプレート内:
<form [formGroup]="parentFormGroup">
<input-form-control
[required]="false"
[group]="parentFormGroup"
label="Description"
name="description"
controlId="description"
helpText="Enter the Description"
[value]="someValue"
(valueChange)="checkParentValidity($event)">
</input-form-control>
<form>