具有内置功能的按钮组件已禁用/重新启用(PREVENT DOUBLE SUBMIT!)

时间:2019-06-27 04:33:29

标签: javascript angular asynchronous rxjs angular-cli

处理表单组件本身上的所有“禁用”验证逻辑是否是一个很好的经验法则?听起来对吗?

我真的只是想找到一种在整个应用程序中共享“禁用”逻辑的方法,而不必在每个表单组件中都重复它,但是我想那是做事情的正确方法?有人可以验证吗?

我想创建一个可重用的提交按钮组件。 此提交按钮组件应与其他任何提交按钮组件一样工作,除了一件事情...

单击提交按钮后,需要“禁用自身”。 那应该很容易吧。但是,这里的麻烦之处在于,在“调用”完成100%之后,按钮还需要“重新启用自身”。 (以防万一,或者在完成第一个操作后应用程序需要允许其他操作等)。

我希望组件中100%的“那个”逻辑都存在,以便可以在应用程序中的任何地方轻松地重用它。

我认为这很容易,但是我仍然想念一些东西... 我想这个想法是最好使用@Input()(或可能是Output),以便将某些“异步回调类型的东西”传递给按钮控件本身...

这样,按钮可以对“异步回调类型的事物”完成做出反应,并使用回调处理程序重新启用自身。

感谢您的提前帮助!

1 个答案:

答案 0 :(得分:1)

我写了一个抽象类,在这种情况下,我一直使用它:

import { ElementRef, EventEmitter, Input, Output, ViewChild } from '@angular/core';
import { FormGroup, FormGroupDirective } from '@angular/forms';

export abstract class FormBase<T = any> {
    @Input() isSubmitting: boolean;

    @Output('onSubmit') _submit = new EventEmitter<T>();

    @ViewChild(FormGroupDirective, { static: true })
    ngForm: FormGroupDirective;

    @ViewChild('submitButton', { static: true }) button: ElementRef;

    form: FormGroup;

    onSubmit(): void {
        if (this.isFormValid()) this._submit.emit(this.getFormValue());
    }

    submit(): void {
        if (!this.button || !this.button.nativeElement) return;

        this.button.nativeElement.click();
    }

    reset(value?: any) {
        this.ngForm.resetForm(value);
    }

    isFormValid(): boolean {
        return this.form.valid;
    }

    getFormValue(): T {
        return this.form.value;
    }

    shouldDisable(): boolean {
        return (
            this.isSubmitting ||
            ((this.form.invalid || this.form.pending) &&
                (this.ngForm ? this.ngForm.submitted : true))
        );
    }
}

component.ts

import { FormBase } from 'path';

@Component({
    ...
})
export class FormComponent extends FormBase {
    constructor(formBuilder: FormBuilder) {
        super();
        this.form = formBuilder.group({
            username: ['', Validators.required],
            password: ['', Validators.required],
        });
    }
}

component.html

<form (ngSubmit)="onSubmit()" [formGroup]="form">
    <mat-form-field>
        <mat-label>Username</mat-label>
        <input matInput type="text" formControlName="username" />
    </mat-form-field>
    <mat-form-field>
        <mat-label>Password</mat-label>
        <input matInput type="text" formControlName="password" />
    </mat-form-field>
    <button [disabled]="shouldDisable()" mat-flat-button color="primary">
        Submit
    </button>
</form>

您的表单组件基本上是从此类扩展的,应该可以在99%的时间内工作。如果您的组件需要某些非常特定的功能,例如在禁用按钮时进行更改或进行其他操作,则可以简单地覆盖FormComponent中的方法。