Angular 6 - dirty 和 invalid 未按预期工作
Angular 6 - ng-dirty and ng-invalid not working as expected
我正在尝试一些表单验证并看到来自应用于表单控件的 classes 的奇怪行为。
当我将输入值从 'Rob' 更改为 'Ro' 时,ng-dirty
未被应用,但当我将值进一步更改为 'R' 时,它确实被应用。
ng-invalid
当我清除表单字段并且存在必需属性时,不会应用。但是,如果我模糊了,则会应用 class。
Link 到代码 - https://stackblitz.com/edit/angular-form-classes
我做错了什么?请告诉我谢谢。
我不得不承认我并不完全理解这背后的原因,但是您在尝试显示的 userName.className
上遇到了 "ExpressionChangedAfterItWasChecked" 错误。它似乎首先检查 userName.className
,然后根据更新它的事件对表单状态进行检查,因此它总是落后一步。您可以通过执行额外的更改检测引用循环来同步这些值。
将 ChangeDetectorRef
注入您的组件,并在检查视图后 运行 detectChanges()
。
import { Component, AfterViewChecked, ChangeDetectorRef } from '@angular/core';
import { User } from './user';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent implements AfterViewChecked {
name = 'Angular 6';
topics = ['Angular', 'React', 'Vue'];
userModel = new User('Rob', 'rob@test.com', 5556665566, 'Angular', 'morning', true);
constructor(private ref: ChangeDetectorRef) {}
ngAfterViewChecked() {
this.ref.detectChanges();
}
}
使用模板引用变量 username
在 其在 DOM 中的定义后,它可以正常工作。根据我的测试,它可以在form
标签的内部或外部使用,只要它在输入元素声明之后。
有关演示,请参阅 this stackblitz。
<form #userForm="ngForm" ngForm>
<div class="form-group">
<label>Name</label>
<input type="text" #userName required class="form-control" name="name" [(ngModel)]="userModel.name">
</div>
</form>
{{userName.className}} <<-- Works when positioned after userName definition in the DOM
发生的情况是你总是落后一个变化检测步骤(使用内插类名),因为你正在改变模型,这反过来又改变了输入字段的值,然后你复制了那个输入字段值(通过模板变量)到其他地方。
试试这个 stackblitz:
https://stackblitz.com/edit/angular-form-classes-q97pah?file=src%2Fapp%2Fapp.component.ts
在这里你监听 ngModelChange
,一旦它发生,在下一个勾号 (setTimeout
) 你显示类名值。
我正在尝试一些表单验证并看到来自应用于表单控件的 classes 的奇怪行为。
当我将输入值从 'Rob' 更改为 'Ro' 时,ng-dirty
未被应用,但当我将值进一步更改为 'R' 时,它确实被应用。
ng-invalid
当我清除表单字段并且存在必需属性时,不会应用。但是,如果我模糊了,则会应用 class。
Link 到代码 - https://stackblitz.com/edit/angular-form-classes
我做错了什么?请告诉我谢谢。
我不得不承认我并不完全理解这背后的原因,但是您在尝试显示的 userName.className
上遇到了 "ExpressionChangedAfterItWasChecked" 错误。它似乎首先检查 userName.className
,然后根据更新它的事件对表单状态进行检查,因此它总是落后一步。您可以通过执行额外的更改检测引用循环来同步这些值。
将 ChangeDetectorRef
注入您的组件,并在检查视图后 运行 detectChanges()
。
import { Component, AfterViewChecked, ChangeDetectorRef } from '@angular/core';
import { User } from './user';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent implements AfterViewChecked {
name = 'Angular 6';
topics = ['Angular', 'React', 'Vue'];
userModel = new User('Rob', 'rob@test.com', 5556665566, 'Angular', 'morning', true);
constructor(private ref: ChangeDetectorRef) {}
ngAfterViewChecked() {
this.ref.detectChanges();
}
}
使用模板引用变量 username
在 其在 DOM 中的定义后,它可以正常工作。根据我的测试,它可以在form
标签的内部或外部使用,只要它在输入元素声明之后。
有关演示,请参阅 this stackblitz。
<form #userForm="ngForm" ngForm>
<div class="form-group">
<label>Name</label>
<input type="text" #userName required class="form-control" name="name" [(ngModel)]="userModel.name">
</div>
</form>
{{userName.className}} <<-- Works when positioned after userName definition in the DOM
发生的情况是你总是落后一个变化检测步骤(使用内插类名),因为你正在改变模型,这反过来又改变了输入字段的值,然后你复制了那个输入字段值(通过模板变量)到其他地方。
试试这个 stackblitz: https://stackblitz.com/edit/angular-form-classes-q97pah?file=src%2Fapp%2Fapp.component.ts
在这里你监听 ngModelChange
,一旦它发生,在下一个勾号 (setTimeout
) 你显示类名值。