在Ionic 4中如何处理两个呼叫和加载控制器

时间:2019-02-16 09:02:18

标签: ionic-framework ionic4

我有一个要求,我必须有2个API调用,并且我希望第一个请求的前两个调用在那里。向后导航时会出现第二个API调用。 我正在ngOnInit Webhook中调用第一API,并在ionViewWillEnter Webhook中调用第二API。

我面临的问题是,当两个请求同时完成时,加载程序并没有被消除。

所以我在想的可能的解决方案是,如果我可以在第一次加载时同步调用两个API,然后每次单击后退按钮时又调用另一个API。

注意:我正在拦截器中使用装载程序。

代码:对于拦截器

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

        // Clone the request to add the new header.
        const authReq = req.clone();
        this.showLoading();

        // send the newly created request
        return next.handle(authReq).pipe(catchError((error) => {
            if (error.status === 401) {
                this._navCtrl.navigateForward('/login');
            }
            return throwError(error);
        }), finalize( () => {
            console.log('hi');
            this.dismissLoading();
          })
        );
    }

编辑:

显示加载程序和隐藏加载程序的代码:

    async showLoading() {
        return await this._loadingCtrl.create().then(a => {
            a.present();
        });
    }

    async dismissLoading() {
        return await this._loadingCtrl.dismiss();
    }

3 个答案:

答案 0 :(得分:2)

对于我来说,我将创建一个LoaderService来自己处理加载。特殊的是,我将创建一个名为isShowing的标志,因此,如果已经在显示加载,我们只需要通过再次调用presentLoader函数来更新加载消息。屏幕上只会显示一个“正在加载”弹出窗口。

在您的情况下,我不建议在HTTP Interceptor中显示Loader,因为我们无法在那里处理HTTP调用堆栈。只需创建一个新功能,将所有必要的API调用与开始/结束处理数据时的显示/关闭弹出窗口结合起来即可。

import { LoadingController } from '@ionic/angular';
import { Injectable } from '@angular/core';

@Injectable()
export class LoaderService {
    private loading: HTMLIonLoadingElement;
    private isShowing = false;

    constructor(private loadingController: LoadingController) {}

    public async presentLoader(message: string): Promise<void> {
        if (!this.isShowing) {
            this.loading = await this.loadingController.create({
                message: message
            });
            this.isShowing = true;
            return await this.loading.present();
        } else {
            // If loader is showing, only change text, won't create a new loader.
            this.isShowing = true;
            this.loading.message = message;
        }
    }

    public async dismissLoader(): Promise<void> {
        if (this.loading && this.isShowing) {
            this.isShowing = false;
            await this.loading.dismiss();
        }
    }
}

答案 1 :(得分:1)

  1. 简单的解决方案是只要单击bak按钮就可以进行函数调用,并且在函数内部可以进行API调用。
  2. 您可以使用ionViewWillEnter而不是链接到后退按钮,每次要离开页面时都会调用ionViewWillEnter,但缺点是每次更改视图时都会调用它,无论是否单击后退按钮。

还应该检查,这是您的服务单例,它创建了ionic-loader的单个实例。我认为在您的情况下,将创建多个加载程序实例。

您也可以在页面的showLoading()中调用ionViewWillEnter,在页面hideLoading()中调用ionViewDidEnter(),而不用在拦截器中调用加载程序。

您可以如下所示创建Singleton Loader服务。 该服务将只创建一个离子加载程序实例。

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

import { LoadingController } from '@ionic/angular';

@Injectable({
    providedIn: 'root'
})
export class LoaderService {
    private loader: HTMLIonLoadingElement;

    constructor(private loadingController: LoadingController) {}

    async showLoader() {
        if (!this.loader) {
            this.loader = await this.loadingController.create({ message: 'Loading' });
        }
        await this.loader.present();
    }

    async hideLoader() {
        if (this.loader) {
            await this.loader.dismiss();
            this.loader = null;
        }
    }
}

答案 2 :(得分:0)

   private loading: HTMLIonLoadingElement;
     constructor(public loadingController: LoadingController) { }

     public async show(): Promise<void> {
       return await this.loadingController.create({
         message: 'Please wait...',
         spinner: 'crescent'
       }).then(a => {
         a.present().then(() => {
           console.log('presented');
         });
       });
     }

       return await this.loadingController.dismiss().then(() =>               
    console.log('dismissed'));
      }`enter code here`