2017-07-10 2 views
3

私は、プロセス全体をキャンセルするための「取り消し」ボタンを含むデータ収集コンポーネントを持っています。問題は、Angular 2バリデータで検証されたHTML入力フィールドの一部にフォーカスがあり、有効ではなく、キャンセルボタンを押すと、コンポーネントが削除されないということです。代わりに、バリデーターが起動し、キャンセルボタンの押下は無視されます。コンポーネントを消すために、バリデータが不平を言った後、もう一度押してください。キャンセルボタン自体は、単にコンポーネントからのルーティングをトリガーします。関連コード:角2のフォームバリデーターにキャンセルボタンがついています

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  
} 

私はこれがなぜ起こるかわかりません。何か案は?

あなたのコンポーネントクラスで
<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> 

+0

同様の問題を示す同じ問題は、キャンセルボタン付きのModalフォームで発生します。https://stackoverflow.com/questions/46411390/angular-form-validation-activated-before-cancel-button-is-triggered?rq= 1 – rmcsharry

+0

ありがとう、私はその質問に気づいた。私がこの問題について考えるとき、私のフォームは実際にはぼかしイベントのハンドラを持っていました。これは、ぼかしの入力フィールドをトリムしました。これが原因かどうか疑問に思う? –

+0

いいえ、それは原因ではありません。原因は、ぼやけが発生するとすぐにフォームの検証が行われることです。キャンセルクリックが登録される前に起こります。私はそれを解決する方法の答えを投稿します。 – rmcsharry

答えて

1

はボタンタイプを使用してみてください=のように "リセット" https://angular.io/guide/reactive-forms

で詳しく

revert() { this.ngOnChanges(); } 

を私はあなたを助けるために願っています。

+1

私はフォームをリセットしようとしていませんが、コンポーネント全体を完全に取り消す(削除してください)。私はリセットとしてボタンタイプを宣言しようとしましたが、何も変わりませんでした。 –

1

原因は、ぼかしイベントが発生するとすぐにフォーム検証が実行されるためです。キャンセルクリックが登録される前に起こります。

解決策は1つしかありません。エラーを表示するタイミングを知るために、最初はfalseに設定されているコンポーネントにフラグを設定してください。

妥当性検査で「発火」する場合にのみ、この値をtrueに設定します。

フォームが読み込まれ、ユーザーがフィールドをクリックしてキャンセルをクリックすると、フラグはまだfalseであり、検証は表示されません。ユーザーが送信をクリックすると、フラグがオンになり、検証が表示されます。

たとえば、このフォームには、検証エラーを表示するために使用されるスパンブロックがあり、フラグは*ngIfで保護されています。また、入力自体の '検査フィールド'クラスも保護されています - これは、エラーがある場合に入力の周りに赤い枠線を追加するだけです。したがって、赤い枠線と検証エラーが表示されるには、フラグが真でなければなりません。

次のように開始しOnSubmitの
<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(data: any):void { 
    this.isShowError = true; 
    if (this.form.valid) ... 

。フラグが偽になるので、フィールドがフォーカスを失ったときには表示されません。

しかし、次のように醜いハックでそれを得ることができるかもしれません(フォーム上のすべてのフィールドにぼかしハンドラが必要なので厄介です)。

ユーザーがキャンセルボタンをクリックしたときに追跡するために、別のフラグを追加し、フォーム上の各フィールドに対して、(ぼかし)ハンドラでは、このように、タイムアウト時間内にそれを確認してください。

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

その後でハンドラをクリックしてキャンセル:

this.userClickedCancel = true; 

これは、タイムアウトはそれが価値だチェックするためのハンドラで有効期限が切れる前にキャンセルコードフラグを変更するべきであることを意味します。

**注:フォームを「却下」されており、また、**

をあなたは離れて航行多分フォーム(またはモーダルを閉じる)「を隠して」されていない場合は、あなたがすべき離れてナビゲートしていない場合また、キャンセルハンドラでisShowErrorフラグをfalseに設定します(ユーザーが送信を要求し、フォームが無効で、キャンセルをクリックしてフォームを再読み込みする場合)。

関連する問題