如何在 Angular 2 上实现 ngOnChanges 以进行输入验证,而不触发“检查后表达式已更改。”错误
Posted
技术标签:
【中文标题】如何在 Angular 2 上实现 ngOnChanges 以进行输入验证,而不触发“检查后表达式已更改。”错误【英文标题】:How to implement ngOnChanges for input validation on angular 2 without triggering ' Expression has changed after it was checked.' error 【发布时间】:2017-06-14 18:24:04 【问题描述】:我尝试编写自己的自定义组件,该组件使用正则表达式进行基本验证,可以作为组件的输入。有两种情况,一种是表单最初为空(新项目表单),另一种是数据已经存在(编辑)。
问题是,当我在最初设置数据后尝试验证字段时,通常会得到“检查后表达式已更改。”。我明白为什么要进行这项检查以及为什么会发生错误,但我不明白这是什么意思 'ngOnChanges' 如果我不能从中更改组件状态?在这种情况下,状态变化是 'isValid' 布尔标志,它会导致组件边框变为红色。
我尝试了以下方法:
this.changeDetect.detectChanges(),在 ngOnChanges 之前和之后。 将“文本”更改为 getter/setter 对。将验证日志移到那里。同样的错误。我认为这是 与 ngOnChanges 基本相同,所以没有任何意外。 ngAfterViewInit 不验证代码更新表单的情况(对于 例如,来自后端的查询 -> 已填写编辑表单。)错误 但是不会发生。 将 changeDetection 策略设置为在 @Component 装饰器处推送。 超时...没有变化,如果我设置超时超过 1 秒,则没有任何反应,如果 更少的错误发生。这可能与开发模式检查有关 这似乎发生在初始更改检测后 1 秒。这感觉非常常见和简单的用例,因此我想我在这里错过了一些非常简单的东西。
示例用法:
<cx-form-text-input validate=".+" label="Rekisterinumero*" [(text)]="ticket.registerPlate" format="uppercase"></cx-form-text-input>
示例组件:
@Component(
selector: 'cx-form-text-input',
templateUrl: './form-text-input.component.html',
styleUrls: ['./form-text-input.component.scss']
)
export class FormTextInputComponent implements OnChanges
@Input()
public text: string;
@Output() textChange = new EventEmitter();
@Input() public validate;
@Input() public label: string = 'DEFAULT LABEL';
@Input() public disabled = false;
@Input() format: string;
public entry: FormEntry;
constructor(private form: FormContext, private changeDetect: ChangeDetectorRef)
this.entry = form.Join();
private applyFormat(text: string): string
switch (this.format)
case 'uppercase':
return text.toUpperCase();
default:
return text;
public isDisabled(): boolean
return this.disabled || this.form.disabled;
public keyboardEvent()
this.entry.isDirty = true;
this.text = this.applyFormat(this.text);
this.validateData();
this.textChange.emit(this.text);
private validateData()
if (!this.validate)
this.entry.isValid = true;
return;
if (!this.text)
this.entry.isValid = false;
return;
this.entry.isValid = !!this.text.match(this.validate);
ngOnChanges(changes: SimpleChanges)
this.validateData(); // The painpoint...
错误:
EXCEPTION: Error in ./EditFormComponent class EditFormComponent - inline template:6:72 caused by: Expression has changed after it was checked. Previous value: 'true'. Current value: 'false'.
ORIGINAL EXCEPTION: Expression has changed after it was checked. Previous value: 'true'. Current value: 'false'.
ORIGINAL STACKTRACE:
【问题讨论】:
【参考方案1】: ngOnChanges(changes: SimpleChanges)
this.validateData(); // The painpoint...
this.changeDetect.detectChanges(); // <<<=== invoke change detection at the end of `ngOnChanges` if the model was modified
【讨论】:
已经试过了,i.imgur.com/PnVsfpt.png,没有帮助。那么这应该有效吗?如果是这样,我认为我的代码中可能还有其他原因导致它。或者这是角度 2 中的错误。但是我从 2.1 -> 2.4 开始使用,但仍然会发生这种情况。 错误信息是关于EditFormComponent
并且您问题中的代码显示FormTextInputComponent
。我的答案仅在更改仅影响当前类的模型(FormTextInputComponent
)时才有效。您可以尝试注入private appRef: ApplicationRef
并调用this.appRef.tick()
。
嗯,是的,这很好!明天我会检查一下,如果我可以追踪链回到 EditFormComponent 并找出验证后导致错误的原因。以上是关于如何在 Angular 2 上实现 ngOnChanges 以进行输入验证,而不触发“检查后表达式已更改。”错误的主要内容,如果未能解决你的问题,请参考以下文章
Angular 针对 Asp.Net WebApi,在服务器上实现 CSRF