繁体   English   中英

无法在 Subscribe() 的错误响应中关闭 LoadingController - Ionic 4

[英]Cannot Dismiss LoadingController In Error Response Of Subscribe() - Ionic 4

当用户尝试登录时,我正在显示 LoadingController。 同时,正在调用 API。

当我收到来自订阅的 SUCCESS 响应时,我可以关闭 LoadingController,但是当我收到 ERROR 响应时,我无法关闭。 请帮忙!

我是一名专业的 Python 开发人员,也是 Ionic 的新手,一天前刚刚开始。 所以,请协助。

import { Component, OnInit } from '@angular/core';
import { ToastController, LoadingController } from '@ionic/angular';

import { CallapiService } from '../callapi.service';

@Component({
  selector: 'app-login',
  templateUrl: './login.page.html',
  styleUrls: ['./login.page.scss'],
})
export class LoginPage implements OnInit {

  userEmail = '';
  userPassword = '';
  loginUrl = 'login/';
  loginMethod = 'POST';
  postBody = {};


  constructor(
    public toastController: ToastController,
    public loadingController: LoadingController,
    private callApiService: CallapiService,
  ) { }

  ngOnInit() {
  }

  async presentToast(displayMessage) {
    const toast = await this.toastController.create({
      message: displayMessage,
      duration: 2000,
      position: 'middle',
    });
    return await toast.present();
  }

  async presentLoading(loadingMessage) {
    const loading = await this.loadingController.create({
      message: loadingMessage,
    });
    return await loading.present();
  }


  loginUser() {
    if (this.userEmail === '' || this.userPassword === '') {
      this.presentToast('Email and password are required.');
    }

    else {
      this.presentLoading('Processing...');
      this.postBody = {
        email: this.userEmail,
        password: this.userPassword,
      };
      this.callApiService.callApi(this.loginUrl, this.postBody, this.loginMethod).subscribe(
        (success) => {
          console.log(success);
          this.loadingController.dismiss();
        },
        (error) => {
          console.log(error);
          this.loadingController.dismiss();
        }
      );
      this.loadingController.dismiss();
    }

  }

}

没有任何服务,

我在使用 Ionic 4 加载控制器时遇到的同样问题。 经过反复试验,我得到了有效的解决方案。

由于加载控制器函数使用 async 和 await,因为它们都是异步函数。

dismiss() 函数将在 present() 函数之前调用,因为dismiss 函数不会等到创建和呈现加载器,它会在present() 函数调用之前触发。

下面是工作代码,

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

   presentLoading() {
     if (this.loading) {
       this.loading.dismiss();
     }
     return new Promise((resolve)=>{
       resolve(this.loadingController.create({
        message: 'Please wait...'
      }));
     })
   }

  async dismissLoading(): Promise<void> {
    if (this.loading) {
      this.loading.dismiss();
    }
  }

  someFunction(){
    this.presentLoading().then((loadRes:any)=>{
      this.loading = loadRes
      this.loading.present()

      someTask(api call).then((res:any)=>{
        this.dismissLoading();
      })
    })
  }
this.callApiService.callApi(this.loginUrl, this.postBody, this.loginMethod)
  .subscribe(
    (data) => {
      // Called when success  
    },
    (error) => {
      // Called when error
    },
    () => {
      // Called when operation is complete (both success and error)
      this.loadingController.dismiss();
    });

来源: https : //stackoverflow.com/a/54115530/5442966

使用 Angular 属性绑定。 为您的加载创建一个组件:

import { Component, Input } from '@angular/core';
import { LoadingController } from '@ionic/angular';

@Component({
  selector: 'app-loading',
  template: ''
})
export class LoadingComponent {
  private loadingSpinner: HTMLIonLoadingElement;

  @Input()
  set show(show: boolean) {
    if (show) {
      this.loadingController.create().then(loadingElem => {
        this.loadingSpinner = loadingElem;
        this.loadingSpinner.present();
      });
    } else {
      if (this.loadingSpinner) {
        this.loadingSpinner.dismiss();
      }
    }
  }

  constructor(private loadingController: LoadingController) {}
}

...然后在“login.page.html”中使用您的组件:

...    
<app-loading [show]="showLoading"></app-loading>

...在“登录页面”中创建一个属性“showLoading”并将其设置为 true 或 false 您想要的:

//.... some source code
export class LoginPage implements OnInit {
  showLoading;
  userEmail = '';
  userPassword = '';
  loginUrl = 'login/';
  loginMethod = 'POST';
  postBody = {};

  //.... some source code

  loginUser() {
    if (this.userEmail === '' || this.userPassword === '') {
      this.presentToast('Email and password are required.');
    } else {
      this.showLoading = true;
      this.postBody = {
        email: this.userEmail,
        password: this.userPassword
      };
      this.callApiService
        .callApi(this.loginUrl, this.postBody, this.loginMethod)
        .subscribe(
          success => {
            console.log(success);
            this.showLoading = false;
          },
          error => {
            console.log(error);
            this.showLoading = false;
          }
        );
      this.showLoading = false;
    }
  }
}

这对我有用,我在其他页面上重用加载组件!

推荐阅读: https : //angular.io/start

我实际上遇到了这个确切的问题,对我来说答案就是使用await

用于创建和解除加载器的函数返回承诺。 我意识到正在发生的是订阅/承诺拒绝正在阻止所有其他承诺完成。 现在,我只是等待呈现和解散,我没有问题:

async getData() {  
  //await presenting
  await this.presentLoading('Loading...');

  try {
    let response = await this.httpService.getData();
    await this.loadingController.dismiss();

    //...
  catch(err) {
    this.loadingController.dismiss();
    //handle error
    //...
  }
}

async presentLoading(msg: string) {
  const loading = await this.loadingController.create({
    spinner: 'crescent',
    message: msg
  });
  await loading.present();
}

我希望这个简单的解决方案有帮助!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM