简体   繁体   English

取消旧警报并显示最新警报-Ionic3

[英]Dismiss old alert and present latest alert - Ionic3

I am using the alerts of Ionic 3 and I am facing an issue of alerts stacking up. 我正在使用Ionic 3的警报,并且遇到警报堆积的问题。 I am using the network plugin to check if the user is connected to a network(WiFi/2G/3G etc.) or not and the idea is to trigger an alert every time the user goes offline or comes online. 我正在使用网络插件检查用户是否已连接到网络(WiFi / 2G / 3G等),其想法是每次用户下线或上线时都会触发警报。

this.connectSubscription = this.network.onConnect().subscribe(() => {
  console.log('network connected!');
  let connectedToInternet = this.alertController.create({
    subTitle: 'Connected to Internet',
    buttons: ['OK']
  });
  connectedToInternet.present();
});

this.disconnectSubscription = this.network.onDisconnect().subscribe(() => {
  let noInternetAlert = this.alertController.create({
    subTitle: 'No Internet Connection. Please enable Wifi or Mobile data to continue.',
    buttons: ['OK']
  });
  noInternetAlert.present();
});

Current behaviour: If the user disconnects and reconnects multiple times, for every instance of change in the network, an alert is presented and the alerts stack up on the view until the user manually dismisses the alerts. 当前行为:如果用户多次断开连接并重新连接,则对于网络中的每个更改实例,都会显示一个警报,并且警报会堆积在视图上,直到用户手动解除警报为止。

Required behaviour: If the user disconnects and reconnects multiple times, for every instance of change in network, an alert should be presented while the older alert automatically gets dismissed so that at any given point in time, the user is not presented with more than one instance of any alert on the view. 必需的行为:如果用户多次断开连接并重新连接,则对于网络变化的每个实例,都应显示一个警报,而较旧的警报将自动被关闭,以便在任何给定的时间点,都不会向用户显示多个警报视图上任何警报的实例。

isAvailable: Boolean; //boolean variable helps to find which alert we should dissmiss   
connectedToInternet; //made global to get access 
noInternetAlert; // made global to get access


 this.connectSubscription = this.network.onConnect().subscribe(() => {
      console.log('network connected!');

      if(!this.isAvailable){ //checking if it is false then dismiss() the no internet alert
        this.noInternetAlert.dismiss();
      }
       this.isAvailable =true;

      this.connectedToInternet = this.alertController.create({
        subTitle: 'Connected to Internet',
        buttons: ['OK']
      });
      this.connectedToInternet.present();
    });

    this.disconnectSubscription = this.network.onDisconnect().subscribe(() => {

     if(this.isAvailable){// if it is true then dismiss the connected to internet alert
        this.connectedToInternet.dismiss();
      }
      this.isAvailable = false;
      this.noInternetAlert = this.alertController.create({
        subTitle: 'No Internet Connection. Please enable Wifi or Mobile data to continue.',
        buttons: ['OK']
      });
      this.noInternetAlert.present();
    });

The answer marked correct solves the problem asked in the question but alternatively, there's a more elaborate solution that would cover multiple cases of alerts stacking up, which I have successfully implemented. 标记为正确的答案可以解决问题中提出的问题,但是,或者,还有一个更精致的解决方案,其中涵盖了警报堆叠的多种情况,我已经成功实现了。 I created a wrapper for AlertController using a provider which would maintain the status of every alert and subsequently dismiss the older alert and present the new alert. 我使用提供程序为AlertController创建了包装,该提供程序将维护每个警报的状态,然后关闭较旧的警报并显示新的警报。 The code below is for the provider which is basically the wrapper class I am using for all the alerts that I create in the app: 以下代码用于提供程序,基本上是我用于在应用程序中创建的所有警报的包装器类:

import {AlertController} from 'ionic-angular';
@Injectable()
export class AlertserviceProvider {
  alerts: any[] = [];

  constructor(public alertController: AlertController) {
  }

  newAlert(title, subTitle){
    let alert = this.alertController.create({
      title:title,
      subTitle:subTitle
    });
    this.alerts.push(alert);
    return alert;
  }

  dismissAlert(){
    if(this.alerts.length){
      this.alerts.forEach(element => {
        element.dismiss();
      });
    }
    this.alerts = [];
  }

}

This can be consumed within the page using the following code: 可以使用以下代码在页面内使用它:

import { AlertserviceProvider } from '../../providers/alertservice/alertservice';
...
...
...

constructor(..,public alertHandler: AlertserviceProvider,..) {
...
}
testMethod(){
    //First we dismiss the previous alerts if any
    this.alertHandler.dismissAlert();
    //Creating the new alert
    var testAlert = this.alertHandler.newAlert('Title','SubTitle');
    //Adding buttons to the new alert
    testAlert.addButton({
        text: 'OK',
        role: 'OK',
        handler: () => {
          //Handler actions go here - include the Handler only if required
        }
      });
    testAlert.present();
}

Do NOT forget to import your provider and create a variable for it in the constructor parameters. 不要忘记导入您的提供程序并在构造函数参数中为其创建变量。

If you would like to add multiple buttons, the CSS may get messed up. 如果您想添加多个按钮,CSS可能会混乱。 Please take a look at this answer for that problem: https://stackoverflow.com/a/39188966/4520756 请查看该问题的答案: https : //stackoverflow.com/a/39188966/4520756

Please note that for this solution to work, all your alerts need to be created using this wrapper only. 请注意,要使此解决方案起作用,只需使用此包装器即可创建所有警报。 It will not support the alerts created using the default AlertController provided by Ionic. 它不支持使用Ionic提供的默认AlertController创建的警报。 Hope this helps anyone looking to avoid stacking of alerts! 希望这对希望避免警报堆积的人有所帮助!

For an alternative and simpler solution covering lesser cases, check out this answer: https://stackoverflow.com/a/39940803/4520756 有关覆盖较少情况的替代且更简单的解决方案,请查看以下答案: https : //stackoverflow.com/a/39940803/4520756

Credits: https://stackoverflow.com/a/43318081/4520756 学分: https//stackoverflow.com/a/43318081/4520756

I have done that as shown below.The code is self-explanatory.If you need any explanation please let me know. 我已经做到了,如下所示。代码是不言自明的。如果您需要任何解释,请告诉我。

I have created a povider as shown below. 我创建了一个如下所示的povider

network-state.ts 网络状态

import { Injectable } from '@angular/core';
import { Network } from '@ionic-native/network';
import { ToastController } from "ionic-angular";
import { Subscription } from "rxjs/Subscription";

@Injectable()
export class NetworkStateProvider {

  public isInternetAvailable = true; private connectSubscription$: Subscription = null;

  constructor(private network: Network, private toastCtrl: ToastController) {
  }

  //Watch for internet connection
  public WatchConnection() {
    if (this.connectSubscription$) this.connectSubscription$.unsubscribe();
    this.connectSubscription$ = this.network.onDisconnect().subscribe(() => {
      this.isInternetAvailable = false;
      this.showToast('Internet connection unavailable');
      console.log(this.network.type, this.isInternetAvailable, 'No internet!');
      if (this.connectSubscription$) this.connectSubscription$.unsubscribe();
      this.connectSubscription$ = this.network.onConnect().subscribe(() => {
        console.log('Network connected!');
        setTimeout(() => {
          if (this.network.type === 'wifi' || this.network.type === '4g' || this.network.type === '3g' || this.network.type === '2g' || this.network.type === 'cellular' || this.network.type === 'none') {
            this.isInternetAvailable = true;
            this.showToast('Internet connection available');
            this.WatchConnection();
            console.log(this.network.type, this.isInternetAvailable, 'we got a connection!');
          }
        }, 3000);
      });
    });
  }

  //show Toast
  showToast(message, timeout = 3000) {
    let toast = this.toastCtrl.create({
      message: message,
      duration: timeout,
      position: 'bottom',
    });
    toast.present()
  }

  //check Internet Availability
  checkInternetAvailability(): boolean {
    if (!this.isInternetAvailable) {
      this.showToast('Internet connection unavailable');
       return false;
    } else if (!this.isInternetAvailable) {
      this.showToast('Internet connection unavailable');
      return false;
    } else {
      return true;
    }
  }
}

I have used that provider here: 我在这里使用了该provider

app.component.ts app.component.ts

constructor(private network: NetworkStateProvider,public platform: Platform){
 platform.ready().then(() => {
       this.network.WatchConnection();
    });
}

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

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