Angular 2 / PrimeNG - 检查后表达式已更改。在最后一个无效表单控件上绑定 NgModel
Angular 2 / PrimeNG - Expression has changed after it was checked. Binding NgModel on last invalid form control
我遇到了一个问题,当我表单中的最后一个元素绑定了一个值时,抛出了错误 "Expression has changed after it was checked."。
我会先说这是基于这里的 Angular 2 网站示例 -
https://angular.io/docs/ts/latest/cookbook/dynamic-form.html#!#top
我的应用程序的工作方式是,首先我基于模型在我的表单组件中构建一个带有控件的动态表单。
我的表单组件 html 像这样循环模型中的问题
<form *ngIf="showForm" [formGroup]="formGroup">
<!-- questions-->
<div *ngIf="questions.length > 0">
<div *ngFor="let question of questions">
<question [question]="question" [formGroup]="formGroup"></question>
</div>
</div>
<button pButton type="submit" label="Submit" icon="fa-check-circle-o" iconPos="left"
[disabled]="!formGroup.valid" (click)="submitFinalForm()"></button>
</form>
下面是问题组件html,它使用从表单组件传入的数据通过 ngSwitch 显示某些类型的问题
<label [attr.for]="question.field">
{{ question.question }}
</label>
<div [ngSwitch]="question.type">
<!-- Radio / Checkbox -->
<radio-checkbox-question *ngSwitchCase="1" [formGroup]="formGroup" [question]="question"></radio-checkbox-question>
</div>
最后是单选复选框问题组件
<div *ngIf="showQuestion" [formGroup]="formGroup">
<!-- Radio -->
<div *ngIf="model.radiocheckbox == 'radio'">
<div *ngFor="let label of model.labels; let i = index;">
<p-radioButton name="{{model.field}}"
value="{{i}}"
label="{{label}}"
formControlName="{{model.field}}"
[(ngModel)]="questionAnswerRadio"></p-radioButton>
</div>
</div>
</div>
这里是实际组件TS
import { Component, Input, OnInit } from "@angular/core";
import { FormGroup } from "@angular/forms";
import { RadioCheckboxQuestion } from "../Questions/radio.checkbox.question.model";
@Component({
selector: "radio-checkbox-question",
templateUrl: "radio.checkbox.component.html"
})
export class RadioCheckboxComponent implements OnInit {
@Input() question: any;
@Input() formGroup: FormGroup;
model: RadioCheckboxQuestion = new RadioCheckboxQuestion();
showQuestion: boolean = false;
questionAnswerRadio: string = "";
ngOnInit(): void {
// question essential properties
if (this.question.hasOwnProperty("field") && this.question["field"] &&
this.question.hasOwnProperty("labels") && this.question["labels"]) {
this.model.field = this.question["field"];
this.model.labels = this.question["labels"];
// assume always radio for debugging
this.model.radiocheckbox = "radio";
// set existing answer
if (this.question.hasOwnProperty("QuestionAnswer") && this.question["QuestionAnswer"]) {
if (this.model.radiocheckbox == "radio") {
this.questionAnswerRadio = this.question["QuestionAnswer"];
}
}
this.showQuestion = true;
}
}
}
我也见过很多像下面这样的问题
基本上声明 [(ngModel)] 不应该与动态表单一起使用,但是 primeNG 文档说组件可以与模型驱动的表单一起使用,并且设置答案的唯一方法(据我所知)是[(ngModel)]。我相信这里可能发生的事情是因为我将 formGroup 中的唯一问题设置为 formGroup 在更改检测之间变得有效并导致错误的值
Error in ./FormComponent class FormComponent - inline template:17:48 caused by: Expression has changed after it was checked. Previous value: 'false'. Current value: 'true'.
我发现让变更检测满意我的多嵌套组件和 primeNG 的唯一方法是手动实施完整的变更检测。这基本上意味着我必须在每个组件中添加如下内容
import ChangeDetectorRef
constructor(private change: ChangeDetectorRef)
{}
ngOnInit() {
// code here that inits everything
this.change.markForCheck();
}
除此之外,这会导致更改检测错误以不同且独特的方式在使用 primeNG 的组件中弹出。
从您的模板来看,您似乎同时使用了两种型号的驱动器 (formControlName)
和模板驱动 (ngModel)。
<p-radioButton name="{{model.field}}"
value="{{i}}"
label="{{label}}"
formControlName="{{model.field}}"
[(ngModel)]="questionAnswerRadio"></p-
<radioButton>
请select一种方式,然后重试。
我建议你删除 [(ngModel)]
我遇到了一个问题,当我表单中的最后一个元素绑定了一个值时,抛出了错误 "Expression has changed after it was checked."。
我会先说这是基于这里的 Angular 2 网站示例 - https://angular.io/docs/ts/latest/cookbook/dynamic-form.html#!#top
我的应用程序的工作方式是,首先我基于模型在我的表单组件中构建一个带有控件的动态表单。
我的表单组件 html 像这样循环模型中的问题
<form *ngIf="showForm" [formGroup]="formGroup">
<!-- questions-->
<div *ngIf="questions.length > 0">
<div *ngFor="let question of questions">
<question [question]="question" [formGroup]="formGroup"></question>
</div>
</div>
<button pButton type="submit" label="Submit" icon="fa-check-circle-o" iconPos="left"
[disabled]="!formGroup.valid" (click)="submitFinalForm()"></button>
</form>
下面是问题组件html,它使用从表单组件传入的数据通过 ngSwitch 显示某些类型的问题
<label [attr.for]="question.field">
{{ question.question }}
</label>
<div [ngSwitch]="question.type">
<!-- Radio / Checkbox -->
<radio-checkbox-question *ngSwitchCase="1" [formGroup]="formGroup" [question]="question"></radio-checkbox-question>
</div>
最后是单选复选框问题组件
<div *ngIf="showQuestion" [formGroup]="formGroup">
<!-- Radio -->
<div *ngIf="model.radiocheckbox == 'radio'">
<div *ngFor="let label of model.labels; let i = index;">
<p-radioButton name="{{model.field}}"
value="{{i}}"
label="{{label}}"
formControlName="{{model.field}}"
[(ngModel)]="questionAnswerRadio"></p-radioButton>
</div>
</div>
</div>
这里是实际组件TS
import { Component, Input, OnInit } from "@angular/core";
import { FormGroup } from "@angular/forms";
import { RadioCheckboxQuestion } from "../Questions/radio.checkbox.question.model";
@Component({
selector: "radio-checkbox-question",
templateUrl: "radio.checkbox.component.html"
})
export class RadioCheckboxComponent implements OnInit {
@Input() question: any;
@Input() formGroup: FormGroup;
model: RadioCheckboxQuestion = new RadioCheckboxQuestion();
showQuestion: boolean = false;
questionAnswerRadio: string = "";
ngOnInit(): void {
// question essential properties
if (this.question.hasOwnProperty("field") && this.question["field"] &&
this.question.hasOwnProperty("labels") && this.question["labels"]) {
this.model.field = this.question["field"];
this.model.labels = this.question["labels"];
// assume always radio for debugging
this.model.radiocheckbox = "radio";
// set existing answer
if (this.question.hasOwnProperty("QuestionAnswer") && this.question["QuestionAnswer"]) {
if (this.model.radiocheckbox == "radio") {
this.questionAnswerRadio = this.question["QuestionAnswer"];
}
}
this.showQuestion = true;
}
}
}
我也见过很多像下面这样的问题
Error in ./FormComponent class FormComponent - inline template:17:48 caused by: Expression has changed after it was checked. Previous value: 'false'. Current value: 'true'.
我发现让变更检测满意我的多嵌套组件和 primeNG 的唯一方法是手动实施完整的变更检测。这基本上意味着我必须在每个组件中添加如下内容
import ChangeDetectorRef
constructor(private change: ChangeDetectorRef)
{}
ngOnInit() {
// code here that inits everything
this.change.markForCheck();
}
除此之外,这会导致更改检测错误以不同且独特的方式在使用 primeNG 的组件中弹出。
从您的模板来看,您似乎同时使用了两种型号的驱动器 (formControlName) 和模板驱动 (ngModel)。
<p-radioButton name="{{model.field}}"
value="{{i}}"
label="{{label}}"
formControlName="{{model.field}}"
[(ngModel)]="questionAnswerRadio"></p-
<radioButton>
请select一种方式,然后重试。 我建议你删除 [(ngModel)]