Я использую Angular 5.0.0 и материал 5.2.2.
Эта форма содержит два подвопроса. Пользователь подает заявку два раза в одной форме. Это должно продолжаться, потому что я представляю здесь очень упрощенную версию моей оригинальной формы.
После первой отправки во втором подвопросе я проверяю, установлен ли хотя бы один флажок. Если нет, я делаю this.choicesSecond.setErrors({'incorrect': true});
. это
правильно отключает кнопку submit
. Но это дает ошибку:
`ExpressionChangedAfterItHasBeenCheckedError: выражение изменилось
после того как это было проверено. Предыдущее значение: «true». Текущее значение: «ложь».
Я думаю, что это связано с change detection
. Если я сделаю дополнительное обнаружение изменений с помощью this.changeDetectorRef.detectChanges()
, ошибка исчезнет, но кнопка отправки больше не будет отключена.
Что я делаю не так?
Шаблон:
<mat-card>
<form *ngIf="myForm" [formGroup]="myForm" (ngSubmit)="onSubmit(myForm.value)" novalidate>
<div *ngIf="!subQuestion">
<mat-card-header>
<mat-card-title>
<h3>Which fruit do you like most?</h3>
</mat-card-title>
</mat-card-header>
<mat-card-content>
<mat-radio-group formControlName="choiceFirst">
<div *ngFor="let fruit of fruits; let i=index" class="space">
<mat-radio-button [value]="fruit">{{fruit}}</mat-radio-button>
</div>
</mat-radio-group>
</mat-card-content>
</div>
<div *ngIf="subQuestion">
<mat-card-header>
<mat-card-title>
<h3>Whichs fruits do you like?</h3>
</mat-card-title>
</mat-card-header>
<mat-card-content>
<div *ngFor="let choiceSecond of choicesSecond.controls; let i=index">
<mat-checkbox [formControl]="choiceSecond">{{fruits[i]}}</mat-checkbox>
</div>
</mat-card-content>
</div>
<mat-card-actions>
<button mat-raised-button type="submit" [disabled]="!myForm.valid">Submit</button>
</mat-card-actions>
</form>
</mat-card>
* * Компонент тысяча двадцать-одиной: * * тысяча двадцать-дв
export class AppComponent {
myForm: FormGroup;
fruits: Array<string> = ["apple", "pear", "kiwi", "banana", "grape", "strawberry", "grapefruit", "melon", "mango", "plum"];
numChecked: number = 0;
subQuestion: boolean = false;
constructor(private formBuilder: FormBuilder, private changeDetectorRef: ChangeDetectorRef) { }
ngOnInit() {
this.myForm = this.formBuilder.group({
'choiceFirst': [null, [Validators.required]],
});
let choicesFormArray = this.fruits.map(fruit => { return this.formBuilder.control(false) });
this.myForm.setControl('choicesSecond', this.formBuilder.array(choicesFormArray));
this.onChangeAnswers();
}
onChangeAnswers() {
this.choicesSecond.valueChanges.subscribe(value => {
let numChecked = value.filter(item => item).length;
if (numChecked === 0 ) this.choicesSecond.setErrors({'incorrect': true});
});
}
get choicesSecond(): FormArray {
return this.myForm.get('choicesSecond') as FormArray;
};
onSubmit(submit) {
if (!this.subQuestion) {
this.subQuestion = true;
let numChecked = this.choicesSecond.controls.filter(item => item.value).length;
if (numChecked === 0 ) this.choicesSecond.setErrors({'incorrect': true});
// this.changeDetectorRef.detectChanges()
}
console.log(submit);
}
}