Компонент кнопки со встроенным отключением / повторным включением (ПРЕДОТВРАТИТЕ ДВОЙНУЮ ОТПРАВКУ!) - PullRequest
0 голосов
/ 27 июня 2019

Является ли это хорошим эмпирическим правилом для обработки всей логики «отключить» проверки на самом компоненте формы?Это звучит правильно ??

Я просто пытаюсь найти способ поделиться логикой «отключить» в приложении, не повторяя ее в каждом компоненте формы, но я думаю, что это правильный способ сделать что-то ??Может кто-нибудь проверить это ??

Я хотел бы создать компонент кнопки повторного использования.Этот компонент кнопки отправки должен действовать как любой другой компонент кнопки отправки, за исключением одной вещи ...

После нажатия кнопки отправки необходимо "отключить себя".Это должно быть достаточно легко, верно.Однако, проблема в том, что кнопка также должна «повторно включить себя» после того, как «вызов» завершен на 100%.(В случае ошибки или если приложению необходимо разрешить другое действие после завершения первого и т. Д.).

Я бы хотел, чтобы 100% «этой» логики существовало внутри компонента, чтобы я моглегко использовать его повсюду в приложении.

Я думал, что это будет довольно легко, но я думаю, что я все еще что-то упускаю ... Думаю, идея в том, чтобы использовать @Input () предпочтительно (илиможет быть Output), чтобы передать некоторый «тип вещи с асинхронным обратным вызовом» самому элементу управления кнопки ...

Таким образом, кнопка может реагировать на завершение «асинхронного типа вещи с обратным вызовом» и использовать обратный вызовобработчик для повторного включения.

Спасибо за помощь заранее!

1 Ответ

1 голос
/ 29 июня 2019

Я написал абстрактный класс, который все время использую для этого конкретного случая:

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.

...