Angular 2形式验证器弄乱了取消按钮

时间:2017-07-10 14:58:27

标签: angular angular2-forms cancellation

我有一个数据收集组件,其中包含“取消”按钮以取消整个过程。问题是,如果某些由Angular 2验证器验证的HTML输入字段具有焦点且无效,并且我按下取消按钮,则不会删除该组件。相反,验证器将触发,按下取消按钮将被忽略。在验证器抱怨之后,我必须第二次按下它,使组件消失。取消按钮本身只是触发远离组件的路由。相关代码:

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     
 }

我不知道为什么会这样。有什么想法吗?

4 个答案:

答案 0 :(得分:5)

将事件从(单击)更改为(鼠标按下)。在发生模糊事件之前调用mousedown。

所以代替这个function check_email_exists($email) { if ($this->form_validation->valid_email($email) === FALSE) { $this->form_validation->set_message('check_email_exists', 'Enter a valid email'); return FALSE; } // check if email_exists in the database // if FALSE, set validation message and return FALSE // else return TRUE }

尝试:<button (click)="cancel()">Cancel</button>

答案 1 :(得分:2)

尝试使用按钮类型=“重置”,如:

<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>

在您的组件类中:

revert() { this.ngOnChanges(); }

有关https://angular.io/guide/reactive-forms

的更多信息

我希望能帮助你。

答案 2 :(得分:1)

原因是一旦模糊事件触发,表单验证就会触发。所以它发生在注册取消点击之前。

我只能想出一个解决方法 - 在组件中有一个标志,最初设置为false,以便知道何时显示错误。

只有在您需要验证“触发”时才将其设置为true。

因此,如果表单加载并且用户单击某个字段然后单击“取消”,则该标志仍为false,因此不会显示任何验证。如果用户单击“提交”,则打开该标志,从而显示验证。

例如,此表单有一个span块,用于显示验证错误,并且由*ngIf保护标志。此外,受保护的是输入本身的“检查字段”类 - 如果出现错误,这只会在输入周围添加红色边框。因此,红色边框的标志必须为true,并显示验证错误。

  <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) ...

确保用户点击提交时会显示验证错误。当场失去焦点时,它们不会出现,因为旗帜将是假的。

但是,您可以通过丑陋的黑客来解决这个问题,如下所示(因为您需要为表单上的所有字段设置模糊处理程序,因此很麻烦!)。

添加另一个标记以跟踪用户单击取消按钮的时间,并且对于表单上的每个字段,在(模糊)处理程序中,在超时内检查它,如下所示:

setTimeout(() => {if (!userClickedCancel) this.isShowError = true}, 500);

然后在取消点击处理程序中:

this.userClickedCancel = true;

这意味着取消代码应该在处理程序超时到期之前更改标志以检查它的值。

**注意:如果您“解雇”表格而不是导航**

此外,如果您没有导航但可能“隐藏”表单(或关闭模式),您还应该在取消处理程序中将isShowError标志设置为false(对于用户点击提交的情况,表单无效,然后单击取消,然后再次重新加载表单。

答案 3 :(得分:0)

您可以做的就是将按钮更改为老式的好按钮

    <input type="submit" value="submit" .... /> tag.

并将取消按钮更改为:

    <input type="button" value="cancel" (click)="your event here" />

“提交”按钮将触发表单,因为您已经在调用“提交”事件。

这应该可以解决您的问题或遇到此问题的其他人。