在 ajax 请求期间禁用按钮

And*_*ard 1 angular

我已经在 jquery 和 Angular 1 中看到了很多关于如何在处理 ajax 请求时禁用提交按钮的方法,但不是 Angular 2。

到目前为止,我在模板上有:

<button type="submit" [disabled]="requestSent">Submit</button>
Run Code Online (Sandbox Code Playgroud)

和以下在打字稿中切换它的禁用状态:

requestSent: boolean = false;

this.httpService.addNewAgent(object)
            .subscribe(
            data => {

                this.requestSent = false;


            },
            error => {

                console.log(error.error);

            }
            );
Run Code Online (Sandbox Code Playgroud)

但这对每个组件来说都是相当冗长的。有没有更通用的方法来处理这个问题?也许与拦截器?

And*_*ard 5

感谢 @DmitriyKhirniy 的回复,但我想要一种在 ajax 请求期间禁用按钮的更通用的方法。我找到了一种使用指令、服务和拦截器的方法。因此,使用它,您只需要将属性应用disableDuringAjax到您的按钮上。

模板:

<button type="submit" disableDuringAjax>Sign In</button>
Run Code Online (Sandbox Code Playgroud)

如果您的按钮也因表单验证而禁用,您可以使用:

<button type="submit" disableDuringAjax [formValid]="myForm">Sign In</button>
Run Code Online (Sandbox Code Playgroud)

通过[formValid]简单地提及一般的表单实例,指令将完成其余的工作。

指令(disable-button-during-ajax.directive.ts):

<button type="submit" disableDuringAjax [formValid]="myForm">Sign In</button>
Run Code Online (Sandbox Code Playgroud)

服务(busy.service.ts):

import { Component, OnDestroy, OnInit, Directive, HostListener, HostBinding, ElementRef, Input } from '@angular/core';
import { BusyService } from '../busy.service';
import { Subscription } from 'rxjs/Subscription';
import 'rxjs/add/operator/takeUntil';
import { Subject } from 'rxjs/Subject';

@Directive({
    selector: '[disableDuringAjax]'
})

export class DisableButtonDuringAjax implements OnDestroy, OnInit {

    private ngUnsubscribe: Subject<any> = new Subject();

    @Input() formValid;

    subscription: Subscription;

    constructor(private _busyService: BusyService, private el: ElementRef) {



    }




    checkFormValidation(form)
    {
        if ((form.valid == true)) {
            this.checkAjaxProgress();
        }
        if ((form.valid == false)) {
            this.el.nativeElement.disabled = true;
        }
    }


    checkAjaxProgress()
    {

        this.subscription = this._busyService.busy$
        .takeUntil(this.ngUnsubscribe).subscribe(
            response => {




                if ((response == true)) {
                    this.el.nativeElement.disabled = true;
                }

                if ((response == false)) {
                    this.el.nativeElement.disabled = false;
                }

                // Check form one more time
                if ((this.formValid != null)) {
                    if ((this.formValid.valid == false)) {
                        this.el.nativeElement.disabled = true;
                    }
                }


            }
            );
    }







    ngOnInit() {

        // If there is no form to check validation then just check the ajax progress
        if ((this.formValid == null))
        {
            this.checkAjaxProgress();
        }
        // Else check the forms validation AND ajax progress
        else
        {
            this.checkFormValidation(this.formValid);
            this.formValid.valueChanges.takeUntil(this.ngUnsubscribe).subscribe(data => this.checkFormValidation(this.formValid));
        }



    }


    ngOnDestroy() {
        this.ngUnsubscribe.next();
        this.ngUnsubscribe.complete();
    }




}
Run Code Online (Sandbox Code Playgroud)

拦截器(你自己的拦截器):

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

@Injectable()
export class BusyService {

    numberOfBusyRequests: number = 0;
    numberOfNonBusyRequests: number = 0;

    // Observable navItem source
    private _busySource = new BehaviorSubject<boolean>(null);
    // Observable navItem stream
    busy$ = this._busySource.asObservable();

    constructor() { }

    changeBusy(val) {

        if ((val == true)) {
            this.numberOfBusyRequests = this.numberOfBusyRequests + 1;
        }
        else {
            this.numberOfNonBusyRequests = this.numberOfNonBusyRequests + 1;
        }




        if (this.numberOfBusyRequests == this.numberOfNonBusyRequests) {
            this._busySource.next(false);
        }
        else {
            this._busySource.next(true);
        }




    }
}
Run Code Online (Sandbox Code Playgroud)

确保将指令包含在您的 app.module 或共享模块中。还要确保将服务包含在您的 app.module 中。