Угловые валидаторы 2 форм возятся с кнопкой отмены
У меня есть компонент сбора данных, который включает кнопку "Отмена", чтобы отменить весь процесс. Проблема в том, что если некоторые из полей ввода HTML, которые проверяются валидаторами Angular 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
}
Я понятия не имею, почему это происходит. Есть идеи?
5 ответов
Измените событие с (клик) на (mousedown). Mousedown вызывается до события размытия.
Так что вместо этого <button (click)="cancel()">Cancel</button>
попробуй это: <button (mousedown)="cancel()">Cancel</button>
Попробуйте использовать кнопку type="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>
В вашем классе компонентов:
revert() { this.ngOnChanges(); }
Для получения дополнительной информации в https://angular.io/guide/reactive-forms
Я надеюсь помочь вам.
Причина в том, что проверка формы запускается, как только срабатывает событие размытия. Так происходит до регистрации отмены.
Я могу найти только один обходной путь - в вашем компоненте есть флаг, для которого изначально установлено значение false, чтобы знать, когда показывать ошибки.
Установите значение true только тогда, когда вы хотите, чтобы проверки выполнялись.
Таким образом, если форма загружается, а пользователь нажимает на поле, а затем нажимает кнопку "Отмена", флаг все еще имеет значение false и проверки не отображаются. Если пользователь нажимает кнопку "Отправить", вы включаете флаг, в результате чего отображаются валидации.
Например, эта форма имеет блок span, который используется для отображения ошибок проверки, и защищена *ngIf
для флага. Также защищен класс 'check-field' для самого ввода - он просто добавляет красную рамку вокруг ввода в случае ошибки. Таким образом, флаг должен быть истинным, чтобы красная граница и ошибки валидации отображались.
<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 в обработчике отмены (для случаев, когда пользователь нажимает "Отправить", форма недействительна, затем они нажимают "Отмена", а затем вы снова загружаете форму).
Что вы можете сделать, так это изменить кнопку на старомодную,
<input type="submit" value="submit" .... /> tag.
и измените кнопку отмены на:
<input type="button" value="cancel" (click)="your event here" />
Кнопка отправки вызовет форму, поскольку вы уже вызываете событие отправки.
Это должно решить вашу проблему или кого-либо еще, у кого есть эта проблема.
Я знаю, что я довольно поздно, но это может помочь кому-то!
Если кто-то использует ReactiveForm и добавляет кнопку очистки внутри formGroup и использует метод щелчка, то он обязательно очистит форму! но он также отправит пустую форму на сервер! чтобы предотвратить это, я использую 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>