Angular 2 个表单验证器弄乱了取消按钮
Angular 2 form validators messing with the cancel button
我有一个数据收集组件,其中包含 'cancel' 按钮以取消整个过程。问题是,如果由 Angular 2 个验证器验证的某些 HTML 输入字段具有焦点并且无效,并且我按下取消按钮,则不会删除该组件。相反,验证器将触发并且取消按钮按下将被忽略。在验证器抱怨之后,我必须第二次按下它,以使组件 disappear.Cancel 按钮本身简单地触发远离组件的路由。相关代码:
component.html
<form [formGroup]="addReminderForm" (ngSubmit)="onSubmit(addReminderForm.value)">
<input type="text" [formControl]="addReminderForm.controls['text']" />
<div class="error" *ngIf="addReminderForm.controls['text'].hasError('required') &&
addReminderForm.controls['text'].touched">You must enter reminder text</div>
<button type="submit" [disabled]="!addReminderForm.valid" >Add Reminder</button>
</form>
<button (click)="cancel()">Cancel</button>
component.ts:
ngOnInit() {
this.addReminderForm = this.fb.group({
'text': ['', Validators.compose([Validators.required, Validators.maxLength(20)])]
});
}
cancel() {
// Simply navigate back to reminders view
this.router.navigate(['../'], { relativeTo: this.route }); // Go up to parent route
}
我不知道为什么会这样。有什么想法吗?
尝试使用按钮类型="reset" 例如:
<form [formGroup]="heroForm" (ngSubmit)="onSubmit()" novalidate>
...
<div>
<button type="submit" [disabled]="heroForm.pristine">Save</button>
<button type="reset" (click)="revert()"[disabled]="heroForm.pristine">Revert o Cancel</button>
</div>
</form>
在你的组件中 class:
revert() { this.ngOnChanges(); }
更多信息请见https://angular.io/guide/reactive-forms
希望能帮到你
原因是一旦触发模糊事件就会触发表单验证。所以它发生在注册取消点击之前。
我只能想出一个解决方法 - 在您的组件中设置一个标志,该标志最初设置为 false 以了解何时显示错误。
仅当您希望对 'fire' 进行验证时才将其设置为 true。
因此,如果加载表单并且用户在某个字段中单击然后单击取消,则该标志仍然为 false,因此不会显示任何验证。如果用户单击提交,您将打开标志,导致显示验证。
例如,此表单有一个用于显示验证错误的 span 块,它受标志保护并 *ngIf
。输入本身的 'checking-field' class 也受到保护 - 如果出现错误,这只会在输入周围添加一个红色边框。所以标志必须为真,红色边框和验证错误才会显示。
<form [formGroup]="form" (ngSubmit)="onSubmit(form.value)">
<div class="modal-body">
<input #nameElement id="template-name" (blur)="onBlur($event.target)"
[formControl]="name" (keyup)="keyUp($event)" class="form-control"
[ngClass]="{'checking-field': isShowError}"
placeholder="Name this template">
<span class="help-block" *ngIf="isShowError">
<span class="text-danger" *ngIf="form.get('name').hasError('minlength')">Name is required</span>
<span class="text-danger" *ngIf="form.get('name').hasError('noDifference')">Name must be different</span>
</span>
</div>
</form>
OnSubmit 是这样开始的:
onSubmit(data: any):void {
this.isShowError = true;
if (this.form.valid) ...
确保在用户点击提交时显示验证错误。当字段失去焦点时,它们不会出现,因为该标志将是错误的。
但是,您也许可以通过以下丑陋的 hack 来解决这个问题(也很麻烦,因为您需要为表单上的所有字段使用模糊处理程序!)。
添加另一个标记来跟踪用户何时单击取消按钮,并针对表单上的每个字段,在 (blur) 处理程序中,在超时内检查它,如下所示:
setTimeout(() => {if (!userClickedCancel) this.isShowError = true}, 500);
然后在取消点击处理程序中:
this.userClickedCancel = true;
这意味着取消代码应该在处理程序中的超时到期之前更改标志以检查它的值。
** 注意:如果您是 'dismissing' 表格并且没有离开 **
此外,如果您不是离开导航而是 'hiding' 表单(或关闭模式),您还应该在取消处理程序中将 isShowError
标志设置为 false(对于以下情况)用户点击提交,表单无效,然后他们点击取消,然后您再次重新加载表单)。
将事件从(单击)更改为(鼠标按下)。在模糊事件之前调用 Mousedown。
所以不用这个 <button (click)="cancel()">Cancel</button>
试试这个:<button (mousedown)="cancel()">Cancel</button>
你能做的就是把按钮改成一个好的、老式的
<input type="submit" value="submit" .... /> tag.
并将取消按钮更改为:
<input type="button" value="cancel" (click)="your event here" />
提交按钮将触发表单,因为您已经调用了提交事件。
这应该可以解决您的问题或其他遇到此问题的人。
我知道我来晚了,但它可能对某人有帮助!
如果有人使用 ReactiveForm 并在 formGroup 中添加一个清除按钮并使用 click 方法,那么它肯定会清除表单!但它也会将空白表格提交给服务器!为了防止这种情况,我使用了 2 种方法!
1. Use <i> tag instead of <button>
2. use type = "Reset"
在这两种情况下,单击取消按钮都不会调用服务器 API。
示例:
<button class="example-button-row" type="reset" mat-flat-button color="primary"
(click)="sendEmailGroup.reset()"><i class="material-icons">cleaning_services</i> Clear </button>
我有一个数据收集组件,其中包含 'cancel' 按钮以取消整个过程。问题是,如果由 Angular 2 个验证器验证的某些 HTML 输入字段具有焦点并且无效,并且我按下取消按钮,则不会删除该组件。相反,验证器将触发并且取消按钮按下将被忽略。在验证器抱怨之后,我必须第二次按下它,以使组件 disappear.Cancel 按钮本身简单地触发远离组件的路由。相关代码:
component.html
<form [formGroup]="addReminderForm" (ngSubmit)="onSubmit(addReminderForm.value)">
<input type="text" [formControl]="addReminderForm.controls['text']" />
<div class="error" *ngIf="addReminderForm.controls['text'].hasError('required') &&
addReminderForm.controls['text'].touched">You must enter reminder text</div>
<button type="submit" [disabled]="!addReminderForm.valid" >Add Reminder</button>
</form>
<button (click)="cancel()">Cancel</button>
component.ts:
ngOnInit() {
this.addReminderForm = this.fb.group({
'text': ['', Validators.compose([Validators.required, Validators.maxLength(20)])]
});
}
cancel() {
// Simply navigate back to reminders view
this.router.navigate(['../'], { relativeTo: this.route }); // Go up to parent route
}
我不知道为什么会这样。有什么想法吗?
尝试使用按钮类型="reset" 例如:
<form [formGroup]="heroForm" (ngSubmit)="onSubmit()" novalidate>
...
<div>
<button type="submit" [disabled]="heroForm.pristine">Save</button>
<button type="reset" (click)="revert()"[disabled]="heroForm.pristine">Revert o Cancel</button>
</div>
</form>
在你的组件中 class:
revert() { this.ngOnChanges(); }
更多信息请见https://angular.io/guide/reactive-forms
希望能帮到你
原因是一旦触发模糊事件就会触发表单验证。所以它发生在注册取消点击之前。
我只能想出一个解决方法 - 在您的组件中设置一个标志,该标志最初设置为 false 以了解何时显示错误。
仅当您希望对 'fire' 进行验证时才将其设置为 true。
因此,如果加载表单并且用户在某个字段中单击然后单击取消,则该标志仍然为 false,因此不会显示任何验证。如果用户单击提交,您将打开标志,导致显示验证。
例如,此表单有一个用于显示验证错误的 span 块,它受标志保护并 *ngIf
。输入本身的 'checking-field' class 也受到保护 - 如果出现错误,这只会在输入周围添加一个红色边框。所以标志必须为真,红色边框和验证错误才会显示。
<form [formGroup]="form" (ngSubmit)="onSubmit(form.value)">
<div class="modal-body">
<input #nameElement id="template-name" (blur)="onBlur($event.target)"
[formControl]="name" (keyup)="keyUp($event)" class="form-control"
[ngClass]="{'checking-field': isShowError}"
placeholder="Name this template">
<span class="help-block" *ngIf="isShowError">
<span class="text-danger" *ngIf="form.get('name').hasError('minlength')">Name is required</span>
<span class="text-danger" *ngIf="form.get('name').hasError('noDifference')">Name must be different</span>
</span>
</div>
</form>
OnSubmit 是这样开始的:
onSubmit(data: any):void {
this.isShowError = true;
if (this.form.valid) ...
确保在用户点击提交时显示验证错误。当字段失去焦点时,它们不会出现,因为该标志将是错误的。
但是,您也许可以通过以下丑陋的 hack 来解决这个问题(也很麻烦,因为您需要为表单上的所有字段使用模糊处理程序!)。
添加另一个标记来跟踪用户何时单击取消按钮,并针对表单上的每个字段,在 (blur) 处理程序中,在超时内检查它,如下所示:
setTimeout(() => {if (!userClickedCancel) this.isShowError = true}, 500);
然后在取消点击处理程序中:
this.userClickedCancel = true;
这意味着取消代码应该在处理程序中的超时到期之前更改标志以检查它的值。
** 注意:如果您是 'dismissing' 表格并且没有离开 **
此外,如果您不是离开导航而是 'hiding' 表单(或关闭模式),您还应该在取消处理程序中将 isShowError
标志设置为 false(对于以下情况)用户点击提交,表单无效,然后他们点击取消,然后您再次重新加载表单)。
将事件从(单击)更改为(鼠标按下)。在模糊事件之前调用 Mousedown。
所以不用这个 <button (click)="cancel()">Cancel</button>
试试这个:<button (mousedown)="cancel()">Cancel</button>
你能做的就是把按钮改成一个好的、老式的
<input type="submit" value="submit" .... /> tag.
并将取消按钮更改为:
<input type="button" value="cancel" (click)="your event here" />
提交按钮将触发表单,因为您已经调用了提交事件。
这应该可以解决您的问题或其他遇到此问题的人。
我知道我来晚了,但它可能对某人有帮助!
如果有人使用 ReactiveForm 并在 formGroup 中添加一个清除按钮并使用 click 方法,那么它肯定会清除表单!但它也会将空白表格提交给服务器!为了防止这种情况,我使用了 2 种方法!
1. Use <i> tag instead of <button>
2. use type = "Reset"
在这两种情况下,单击取消按钮都不会调用服务器 API。
示例:
<button class="example-button-row" type="reset" mat-flat-button color="primary"
(click)="sendEmailGroup.reset()"><i class="material-icons">cleaning_services</i> Clear </button>