Angular 爱奥尼亚4号:“;“加载控制器”;dismise()在present()之前调用,它将保留微调器而不解除
我使用“Ionic Loading Controller”显示一个微调器,直到检索到数据,然后它调用“dismise()”将其取消。 它工作正常,但有时当应用程序已经拥有数据时,会在“创建()”和“呈现()”完成之前调用“dismise()”,这将保留微调器而不忽略 我试图调用“loadingController.present().then()”中的数据,但这导致数据速度变慢 这是虫子吗? 如何解决这个问题 我的代码示例:Angular 爱奥尼亚4号:“;“加载控制器”;dismise()在present()之前调用,它将保留微调器而不解除,angular,ionic-framework,angular6,loading,ionic4,Angular,Ionic Framework,Angular6,Loading,Ionic4,我使用“Ionic Loading Controller”显示一个微调器,直到检索到数据,然后它调用“dismise()”将其取消。 它工作正常,但有时当应用程序已经拥有数据时,会在“创建()”和“呈现()”完成之前调用“dismise()”,这将保留微调器而不忽略 我试图调用“loadingController.present().then()”中的数据,但这导致数据速度变慢 这是虫子吗? 如何解决这个问题 我的代码示例: customer: any; constructor(public
customer: any;
constructor(public loadingController: LoadingController, private customerService: CustomerService)
ngOnInit() {
this.presentLoading().then(a => consloe.log('presented'));
this.customerService.getCustomer('1')
.subscribe(customer => {
this.customer = customer;
this.loadingController.dismiss().then(a => console.log('dismissed'));
}
}
async presentLoading() {
const loading = await this.loadingController.create({
message: 'wait. . .',
duration: 5000
});
return await loading.present();
}
这就是我解决问题的方法 我使用了一个布尔变量“isLoading”,在调用disclease()时将其更改为false。 完成present()后,如果“isLoading”==false(表示已调用disclose()),则它将立即解除 另外,我在一个服务中编写了代码,这样我就不必在每个页面中再次编写代码 加载.service.ts
import { Injectable } from '@angular/core';
import { LoadingController } from '@ionic/angular';
@Injectable({
providedIn: 'root'
})
export class LoadingService {
isLoading = false;
constructor(public loadingController: LoadingController) { }
async present() {
this.isLoading = true;
return await this.loadingController.create({
// duration: 5000,
}).then(a => {
a.present().then(() => {
console.log('presented');
if (!this.isLoading) {
a.dismiss().then(() => console.log('abort presenting'));
}
});
});
}
async dismiss() {
this.isLoading = false;
return await this.loadingController.dismiss().then(() => console.log('dismissed'));
}
}
然后从页面中调用present()和disclose()
这个例子是:
customer: any;
constructor(public loading: LoadingService, private customerService: CustomerService)
ngOnInit() {
this.loading.present();
this.customerService.getCustomer('1')
.subscribe(
customer => {
this.customer = customer;
this.loading.dismiss();
},
error => {
console.log(error);
this.loading.dismiss();
}
);
或者,您必须更改调用加载的代码,如下所示
async ngOnInit() {
const loading = await this.loadingController.create();
await loading.present();
this.customerService.getCustomer('1')
.subscribe(customer => {
this.customer = customer;
loading.dismiss();
}
}
我正在使用一个类似的解决方案,但依赖于加载覆盖的ID,并让Ionic加载控制器管理应该在顶部的覆盖 装载服务 使用LoadingService的组件/服务
对于离子4,检查此溶液 来源
我也面临着同样的问题,也许我有一个更简单、更可靠的解决方案,使用离子事件本身。这对我有用。它将等待直到创建加载程序,然后才执行服务调用,并且只有当服务调用完成时,才解除加载程序。我希望这有帮助
yourFuncWithLoaderAndServiceCall(){
this.presentLoading().then(()=>{
this.xyzService.getData(this.ipObj).subscribe(
res => {
this.dismissLoading();
this.dismissLoading().then(() => {
this.responseObj = res;
})
}
});
}
async presentLoading() {
this.loader = await this.loadingController.create({
translucent: true
});
await this.loader.present();
}
async dismissLoading() {
await this.loader.dismiss();
}
虽然接受的解决方案可以工作…但我认为最好始终加载一个。我的解决方案将取消以前的加载(如果存在),并创建新的加载。我通常只想一次显示一个加载(我的特定用例),所以这个解决方案适合我
公认的解决方案提出了可能的孤立载荷问题。但这是一个很好的起点简单的方法是添加setTimeOut函数:
setTimeout(() => {
this.loading.dismiss();
}, 2000);
我也有同样的问题,显然我是通过先找出问题来解决的。这个问题发生在加载程序的持续时间到期时,因此它基本上在没有我们完全控制的情况下被解除 现在,它可以正常工作,直到您也手动使用
discouse()
因此,如果要手动使用disclose()
和duration,请在创建时删除duration。然后使用setTimeout()
// create loader
this.loader = this.loadingCtrl.create()
// show loader
this.loader.present().then(() => {})
// add duration here
this.loaderTimeout = setTimeout(() => {
this.hideLoader()
}, 10000)
然后在这里创建隐藏加载程序
// prepare to hide loader manually
hideLoader() {
if (this.loader != null) {
this.loader.dismiss();
this.loader = null
}
// cancel any timeout of the current loader
if (this.loaderTimeout) {
clearTimeout(this.loaderTimeout)
this.loaderTimeout = null
}
}
应在调用.present()函数之后创建此OnDidDisclesh()事件
例如:
this.loader.present().then(() => {
this.loader.onDidDismiss(() => {
console.log('Dismiss');
})
});
这里有同样的问题,这里是我的解决方案(离子4和角度7): 从acepted解决方案开始 现在创建加载一次 在dismise函数中,仅当dimis返回true时,我才将isShowing设置为false
import { Injectable } from '@angular/core';
import { LoadingController } from '@ionic/angular';
@Injectable({
providedIn: 'root'
})
export class LoadingService {
isDismissing: boolean;
isShowing: boolean;
constructor(public loadingController: LoadingController) {
}
async present() {
if(this.isShowing){
return
}
this.isShowing = true
await this.loadingController.create({spinner: "dots"}).then(re => {
re.present()
console.log("LoadingService presented", re.id)
})
}
async dismiss() {
if(this.isShowing){
await this.loadingController.dismiss().then(res => {
if(res){
this.isShowing = false
console.log("LoadingService dismissed", res);
}
})
}
}
}
下面是我如何在我的项目中解决相同问题的。我在HTTP拦截器中使用此服务来显示应用程序中所有REST API调用的加载程序 加载.service.ts
import {Injectable} from '@angular/core';
import {LoadingController} from '@ionic/angular';
@Injectable({
providedIn: 'root'
})
export class LoadingService {
constructor(public loadingController: LoadingController) {
}
async present(options: object) {
// Dismiss all pending loaders before creating the new one
await this.dismiss();
await this.loadingController
.create(options)
.then(res => {
res.present();
});
}
/**
* Dismiss all the pending loaders, if any
*/
async dismiss() {
while (await this.loadingController.getTop() !== undefined) {
await this.loadingController.dismiss();
}
}
}
在原始问题上下文中,可使用如下方式:
...
import {LoadingService} from '/path/to/loading.service';
...
customer: any;
constructor(public loadingService: LoadingService, private customerService: CustomerService)
ngOnInit() {
this.loadingService.present({
message: 'wait. . .',
duration: 5000
});
this.customerService.getCustomer('1')
.subscribe(customer => {
this.customer = customer;
this.loadingService.dismiss();
}
}
我知道这个问题是一年前提出的。我也面临同样的问题。我只想发布我的解决方案。我希望即将到来的访客能得到帮助
async dismissLoading(){
控制台日志(“解散”);
this.isLoading=false;
}
专用异步呈现加载(msg){
控制台日志(“加载”);
const loading=等待this.loadingCtrl.create({
讯息:msg,,
});
等待加载。当前();
变量计时器=设置间隔(()=>{
如果(!this.isLoading){
loading.dispose();
清除间隔(计时器);
控制台日志(“设置解除”);
}
}, 1000);
}
异步加载msg(){
this.isLoading=true;
等待此消息。正在加载(“请稍候…”);
}
尝试了所有方法后,我终于想到了以下方法。到目前为止似乎运作良好
尝试使用500毫秒间隔的setInterval。我还尝试保持函数的非异步性,以便在消费端轻松使用
import { Injectable } from '@angular/core';
import { LoadingController } from '@ionic/angular';
@Injectable({ providedIn: 'root' })
export class UiService {
constructor(private loading: LoadingController) { }
private loader: HTMLIonLoadingElement;
private loaderLoading = false;
public showLoading(message: string) {
this.loaderLoading = true;
this.loading.create({
message,
showBackdrop: true
}).then(load => {
this.loader = load;
load.present().then(() => { this.loaderLoading = false; });
});
}
public dismissLoading() {
const interval = setInterval(() => {
if (this.loader || !this.loaderLoading) {
this.loader.dismiss().then(() => { this.loader = null; clearInterval(interval)});
} else if (!this.loader && !this.loaderLoading) {
clearInterval(interval);
}
}, 500);
}
}
使用列表对我更有效
import { Injectable } from '@angular/core';
import { LoadingController } from '@ionic/angular';
@Injectable({providedIn: 'root'})
export class LoadingService {
private loaders = new Array<HTMLIonLoadingElement>();
constructor(public loadingController: LoadingController) { }
present(options?: object) {
if (this.loaders.length === 0) {
this.loadingController.create(options).then(loader => {
this.loaders.push(loader);
loader.present();
});
}
}
async dismiss() {
if (this.loaders && this.loaders.length > 0) {
this.loaders.forEach(async loader => {
await loader.dismiss()
.then(() => {
loader = null;
})
.catch(e => console.log(e))
.finally(() => this.loaders = new Array<HTMLIonLoadingElement>());
});
}
}
}
从'@angular/core'导入{Injectable};
从'@ionic/angular'导入{LoadingController};
@可注射({providedIn:'root'})
导出类装入服务{
私有加载程序=新数组();
构造函数(公共加载控制器:加载控制器){}
当前(选项?:对象){
if(this.loaders.length==0){
这个.loadingController.create(选项)。然后(loader=>{
这个。装载机。推(装载机);
loader.present();
});
}
}
异步解雇(){
if(this.loaders&&this.loaders.length>0){
this.loaders.forEach(异步加载程序=>{
等待加载程序。解除()
.然后(()=>{
加载器=null;
})
.catch(e=>console.log(e))
.finally(()=>this.loaders=new Array());
});
}
}
}
我在使用Ionic 4加载控制器时遇到了同样的问题。
经过反复试验,我得到了有效的解决方案
因为加载控制器函数都是异步函数,所以使用async和await
函数将在present()函数之前调用,因为discouse函数不会等到创建和呈现加载程序时才调用,它将在函数调用时立即在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();
})
})
}
加载:htmlionladingelement;
构造函数(公共加载控制器:加载控制器){}
当前加载(){
如果(本次加载){
this.loading.disclose();
}
返回
import { Injectable } from '@angular/core';
import { LoadingController } from '@ionic/angular';
@Injectable({ providedIn: 'root' })
export class UiService {
constructor(private loading: LoadingController) { }
private loader: HTMLIonLoadingElement;
private loaderLoading = false;
public showLoading(message: string) {
this.loaderLoading = true;
this.loading.create({
message,
showBackdrop: true
}).then(load => {
this.loader = load;
load.present().then(() => { this.loaderLoading = false; });
});
}
public dismissLoading() {
const interval = setInterval(() => {
if (this.loader || !this.loaderLoading) {
this.loader.dismiss().then(() => { this.loader = null; clearInterval(interval)});
} else if (!this.loader && !this.loaderLoading) {
clearInterval(interval);
}
}, 500);
}
}
import { Injectable } from '@angular/core';
import { LoadingController } from '@ionic/angular';
@Injectable({providedIn: 'root'})
export class LoadingService {
private loaders = new Array<HTMLIonLoadingElement>();
constructor(public loadingController: LoadingController) { }
present(options?: object) {
if (this.loaders.length === 0) {
this.loadingController.create(options).then(loader => {
this.loaders.push(loader);
loader.present();
});
}
}
async dismiss() {
if (this.loaders && this.loaders.length > 0) {
this.loaders.forEach(async loader => {
await loader.dismiss()
.then(() => {
loader = null;
})
.catch(e => console.log(e))
.finally(() => this.loaders = new Array<HTMLIonLoadingElement>());
});
}
}
}
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();
})
})
}
import { Injectable } from '@angular/core';
import { LoadingController } from '@ionic/angular';
@Injectable({
providedIn: 'root'
})
export class LoadingService {
isLoading = false;
loaderCounter = 0;
loading: HTMLIonLoadingElement;
constructor(public loadingController: LoadingController) {}
async present() {
this.loaderCounter = this.loaderCounter + 1;
if (this.loaderCounter === 1) {
this.isLoading = true;
const { loadingDuration, loadingMessage = loadingDefaultOptions.loadingMessage, loadingCssClass } = options;
this.loading = await this.loadingController.create({
duration: loadingDuration,
message: loadingMessage,
cssClass: loadingCssClass
});
await this.loading.present();
}
}
async dismiss() {
this.loaderCounter = this.loaderCounter - 1;
if (this.loaderCounter === 0) {
this.isLoading = false;
await this.loading.dismiss();
}
}
}
async showLoading(loadingId: string, loadingMessage: string = 'Loading...') {
const loading = await this.loadingCtrl.create({
id: loadingId,
message: loadingMessage,
spinner: 'circles'
});
return await loading.present();
}
async dismissLoader(loadingId: string) {
return await this.loadingCtrl.dismiss(null, null, loadingId).then(() => console.log('loading dismissed'));
}
await this.globalVars.showLoading('ifOfLoading')
this.globalVars.dismissLoader('ifOfLoading')
@Injectable()
export class LoaderSerive {
private status: 'pending' | 'dismissed' | 'present' = 'dismissed';
constructor(public loadingCtrl: LoadingController) {}
public show() {
if (this.status === 'present') {
this.hide();
}
this.status = 'pending';
this.loadingCtrl.create({
id: 'spoon-indicator-1',
spinner: null,
message: `
<div>
<div class="loading-indicator--position">
<div class="loading-indicator">
<div class="bowl">
<div class="spoon"></div>
<div class="bowl-content"></div>
</div>
</div>
</div>
</div>`,
duration: 6000
})
.then((loader) => loader.present())
.then(() => {
if (this.status === 'pending') {
this.status = 'present';
} else {
this.hide();
}
});
}
public hide() {
this.loadingCtrl
.dismiss(null, undefined, 'spoon-indicator-1')
.catch((err) => Utilities.log('Loader error!', err))
.then(() => this.status = 'dismissed');
}
}
async presentLoading() {
this.loadingPresent = true;
const loading = await this.loadingController.create({
message: 'Loading...',
});
return await loading.present();
}
async dismissLoading() {
if (this.loadingPresent) {
await this.loadingController.dismiss();
}
this.loadingPresent = false;
}
import { Injectable } from '@angular/core';
import { LoadingController } from '@ionic/angular';
import { LoadingOptions } from '@ionic/core';
import { TranslateService } from '@ngx-translate/core';
import { isNil } from 'lodash-es';
import { BehaviorSubject } from 'rxjs';
import { filter } from 'rxjs/operators';
enum LoadingTypeEnum {
show,
hide,
message,
}
@Injectable({
providedIn: 'root',
})
export class LoadingService {
/**
* this is a special behavior subject we can use on an inital load to show or hide a background etc.
* EXAMPLE: on inital profile load, we might want to have ngIf on an overlay and simply listen for this event.
*/
public appLoaded$ = new BehaviorSubject<boolean>(false);
public loading$: BehaviorSubject<{ type: LoadingTypeEnum; data?: any }> = new BehaviorSubject<any>({ type: LoadingTypeEnum.hide });
loadingState: { type: LoadingTypeEnum; data?: any } = null;
public loading: HTMLIonLoadingElement = null;
public loaderLoaded = false;
public i;
public spinningUp = false;
constructor(private loadingController: LoadingController, private translate: TranslateService) {
const l$ = this.loading$.pipe();
l$.pipe(filter((l) => l.type === LoadingTypeEnum.show)).subscribe((l) => this.showLoading(l.data));
l$.pipe(filter((l) => l.type === LoadingTypeEnum.hide)).subscribe(() => this.hideLoading());
}
show(opts?: LoadingOptions) {
if (isNil(opts)) {
opts = {
message: 'Please wait...', // this.translate.instant('PLEASE_WAIT'),
};
}
this.loading$.next({ type: LoadingTypeEnum.show, data: opts });
}
hide() {
this.loading$.next({ type: LoadingTypeEnum.hide });
}
message(m: string) {
this.loading$.next({ type: LoadingTypeEnum.message, data: m });
}
private async showLoading(opts: LoadingOptions) {
if (!this.loading && !this.spinningUp) {
this.spinningUp = true;
this.loading = await this.loadingController.create(opts);
await this.loading.present();
this.spinningUp = false;
}
}
private async hideLoading() {
const t = setTimeout(() => {
if (this.loading && !this.spinningUp) {
this.loading.dismiss().then(() => {
this.loading = null;
this.spinningUp = false;
clearTimeout(t);
});
}
}, 1000);
}
}
import {Injectable} from '@angular/core';
import {LoadingController} from '@ionic/angular';
import {BehaviorSubject, of} from 'rxjs';
import {filter, pairwise, scan, switchMap} from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class LoadingService {
private dialog;
private toggleLoading$ = new BehaviorSubject<number>(0);
constructor(private loadingController: LoadingController) {
this.toggleLoading$.pipe(
scan((acc, curr) => acc + curr, 0),
pairwise(),
switchMap(([prev, curr]) => {
if (prev <= 0 && curr > 0) {
return this.loadingController.create();
}
if (prev > 0 && curr <= 0) {
this.dialog?.dismiss();
}
return of(null)
}),
filter(d => !!d)
).subscribe((d) => {
d.present();
this.dialog = d;
});
}
showLoading() {
this.toggleLoading$.next(1);
}
hideLoading() {
this.toggleLoading$.next(-1);
}
}
setTimeout(() => {
this.loading.dismiss();
}, 1500)