【问题标题】:Dismiss old alert and present latest alert - Ionic3关闭旧警报并显示最新警报 - Ionic3
【发布时间】:2018-02-05 17:34:43
【问题描述】:

我正在使用 Ionic 3 的警报,但我遇到了警报堆积的问题。 我正在使用网络插件来检查用户是否连接到网络(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();
});

当前行为:如果用户多次断开连接并重新连接,则对于网络中的每个更改实例,都会显示一个警报,并且警报会在视图上叠加,直到用户手动关闭警报.

必需的行为:如果用户多次断开连接并重新连接,则对于网络中的每个更改实例,都应显示警报,而旧警报会自动消失,以便在任何给定时间点,用户不会在视图上看到多个警报实例。

【问题讨论】:

    标签: angular cordova typescript ionic2 ionic3


    【解决方案1】:

    我已经做到了,如下所示。代码是不言自明的。如果您需要任何解释,请告诉我。

    我创建了一个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;
        }
      }
    }
    

    我在这里用过provider

    app.component.ts

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

    【讨论】:

    • 感谢代码 Sampath。您的想法很好,但我正在尝试显示警报而不是 toast 消息,并且我不想在超时时关闭它们。
    • 感谢 Sampath 的这段代码。它帮助我解决了另一个问题!
    • 很高兴听到这个消息。干杯:)
    【解决方案2】:
    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();
        });
    

    【讨论】:

      【解决方案3】:

      标记为正确的答案解决了问题中提出的问题,但或者,有一个更复杂的解决方案可以涵盖多个警报叠加的情况,我已经成功实施。我使用提供程序为 AlertController 创建了一个包装器,该提供程序将维护每个警报的状态,然后关闭旧警报并呈现新警报。下面的代码适用于提供程序,它基本上是我用于在应用程序中创建的所有警报的包装类:

      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 = [];
        }
      
      }
      

      这可以使用以下代码在页面内使用:

      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();
      }
      

      不要忘记导入您的提供程序并在构造函数参数中为其创建一个变量。

      如果您想添加多个按钮,CSS 可能会搞砸。请看一下这个问题的答案:https://stackoverflow.com/a/39188966/4520756

      请注意,要使此解决方案起作用,您的所有警报都需要仅使用此包装器创建。它不支持使用 Ionic 提供的默认 AlertController 创建的警报。希望这可以帮助任何希望避免堆叠警报的人!

      对于涵盖较小情况的替代且更简单的解决方案,请查看此答案:https://stackoverflow.com/a/39940803/4520756

      致谢:https://stackoverflow.com/a/43318081/4520756

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多