Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/32.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 爱奥尼亚4号:“;“加载控制器”;dismise()在present()之前调用,它将保留微调器而不解除_Angular_Ionic Framework_Angular6_Loading_Ionic4 - Fatal编程技术网

Angular 爱奥尼亚4号:“;“加载控制器”;dismise()在present()之前调用,它将保留微调器而不解除

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

我使用“Ionic Loading Controller”显示一个微调器,直到检索到数据,然后它调用“dismise()”将其取消。 它工作正常,但有时当应用程序已经拥有数据时,会在“创建()”和“呈现()”完成之前调用“dismise()”,这将保留微调器而不忽略

我试图调用“loadingController.present().then()”中的数据,但这导致数据速度变慢

这是虫子吗? 如何解决这个问题

我的代码示例:

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)