Angular 7 Form ExpressionChangedAfterItHasBeenCheckedError - 有条件的输入字段

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

在我的一个 Angular 7 表单中,我试图让输入字段基于其他用户的输入值。这是我的html代码。

div>
     <form [formGroup]="UserForm" #UserAdd="ngForm">               
        <mat-form-field>
            <mat-label>Gender</mat-label>
            <mat-select [(value)]="gentype" [formControl]="gendertype" required>
                <mat-option value="Male">Male</mat-option>
                <mat-option value="Female">Female</mat-option>
            </mat-select>
            <mat-error *ngIf="gendertype.hasError('required')">
                Gender is required.
            </mat-error>
        </mat-form-field>       
        <mat-form-field>
            <mat-label>Enrolled</mat-label>
            <mat-select [(value)]="enrol" [formControl]="enrolled" required>
                <mat-option value="No">No</mat-option>
                <mat-option value="Yes">Yes</mat-option>
            </mat-select>
        </mat-form-field>
        <mat-form-field class="form-element" *ngIf="enrol=='Yes'">
            <mat-label>User Preference</mat-label>
            <input matInput [placeholder]="gentype=='Male' ? 'Chicago' : 'Milan'" formControlName="preference" [required]="true" autocomplete="off">
            <mat-error *ngIf="preference.touched && !preference.required">
                Preference is required.
            </mat-error>
        </mat-form-field>
    </form>
    <button mat-raised-button color="primary" type="button" (click)="Save();"[disabled]="!UserAdd.form.valid">SAVE</button>
</div>

Component.ts代码。

private UserForm: FormGroup; 
ngOnInit() {
    this.createForm()   
  }
createForm() {
    console.log('in createForm')
    this.UserForm = new FormGroup({
            gendertype: new FormControl(), 
            enrolled: new FormControl('No'),
            preference: new FormControl('')
    })
  }  
get gendertype() { return this.UserForm.get('gendertype') }
get enrolled() { return this.UserForm.get('enrolled') }
get preference() { return this.UserForm.get('preference') }

我面临的问题是,当用户选择 "enrol-No "时,表单处于无效状态,并且SAVE按钮被禁用。如果用户选择 "报名-Yes",我得到错误提示

ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'disabled: false'. Current value: 'disabled: true'. 

请建议,我错在哪里,以及处理这种情况的好方法。

angular angular-forms
1个回答
1
投票

你得到这个错误是因为你在偏好表单控件上有必要的属性绑定。当使用反应式表单时,你必须使用验证器函数来包含对表单控件的验证。

你可以在FormControl上使用disable属性来动态地禁用和启用formControl。

组件.ts

createForm() {
    console.log('in createForm')
    this.UserForm = new FormGroup({
            gendertype: new FormControl(), 
            enrolled: new FormControl('No'),
            preference: new FormControl({value: '', disabled:true}, Validators.required)
    })
}  

在模板端,您可以使用 entrolled 控件值属性检查用户是否注册。

组件.html

<mat-form-field class="form-element" *ngIf="enrolled.value=='Yes'">
            <mat-label>User Preference</mat-label>
            <input matInput [placeholder]="gentype=='Male' ? 'Chicago' : 'Milan'" formControlName="preference"  autocomplete="off">
            <mat-error *ngIf="preference.touched && !preference.required"> 
                Preference is required.
            </mat-error>
   </mat-form-field>

最后监听注册控件上的valueChanges,以禁用和启用偏好表单控件。

组件.ts

this.createForm();
    (this.enrolled as FormControl).valueChanges.subscribe(hasEntrolled=>{
     if(hasEntrolled === 'Yes'){
        (this.preference as FormControl).enable();
     }else{
          (this.preference as FormControl).disable();
     }
    });

例子


0
投票

绑定控件,而不是使用 [formControl]='gendertype,使用 formControlName='gendertype'. 这将使用表单控件实例进行绑定,而不依赖于 get 函数,这就是引发表达式更改错误的原因。这就是触发expressionChanged错误的原因。

如果这没有帮助,请创建一个样本stackblitz,以便最小化复制。

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