[英]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();
});
使用 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.