在离子应用中监控在线和离线状态

时间:2016-05-12 15:51:36

标签: angularjs cordova ionic-framework

我想实时监控用户的设备是在线还是离线。 我基本上使用了这个网站的信息:http://www.joshmorony.com/monitoring-online-and-offline-states-in-an-ionic-application/

我正在“升级”代码,但我仍然遇到接收实时网络状态变化的问题。在我的工厂里有一个名为startWatching()的功能,它工作得非常棒 - 在工厂内部和我访问第一次时间之后。

我的问题:如何实时访问控制器内网络状态的变化?我需要在每次设备离线时向用户显示一些信息。

我的控制器:

  // ### News ###
  var newsCtrl = function ($scope, $http, $ionicLoading, PostService, BookMarkService, ConnectivityMonitor) {
    console.log('newsCtrl');

    var showNews = false;
    ConnectivityMonitor.startWatching().then(function(result) {
      // promise
      console.log('ConnectivityMonitor result: ', result);
      showNews = result;
      $scope.showNews = showNews;

      console.log('showNews: ', showNews);
      if(showNews) {
        displayNews();
      }
    }, function(error) {
      console.error(error);
    });

    function displayNews() {
      // do some stuff
    }
  };
  newsCtrl.$inject = ['$scope', '$http', '$ionicLoading', 'PostService', 'BookMarkService', 'ConnectivityMonitor'];

我的工厂:

// ### ConnectivityMonitor ###
var ConnectivityMonitor = function ($rootScope, $cordovaNetwork, $q) {
console.log('ConnectivityMonitor');

var monitorNow = {
  isOnline: isOnline,
  isOffline: isOffline,
  startWatching: startWatching
};
var deferred = $q.defer();

function isOnline() {
  if(ionic.Platform.isWebView()) {
    deferred.resolve($cordovaNetwork.isOnline());
  } else {
    deferred.resolve(navigator.onLine);
  }
  return deferred.promise;
};

 function isOffline() {
  if(ionic.Platform.isWebView()) {
    deferred.resolve(!$cordovaNetwork.isOnline());
  } else {
    deferred.resolve(!navigator.onLine);
  }
  return deferred.promise;
};

function startWatching() {
  if(ionic.Platform.isWebView()){
    $rootScope.$on('$cordovaNetwork:online', function(event, networkState) {
      console.log("went online");
      console.log("event: ", event);
      console.log("networkState: ", networkState);
      deferred.resolve($cordovaNetwork.isOnline());
    });
    $rootScope.$on('$cordovaNetwork:offline', function(event, networkState) {
      console.log("went offline");
      console.log("event: ", event);
      console.log("networkState: ", networkState);
      deferred.resolve(!$cordovaNetwork.isOnline());
    });
  }
  else {
    window.addEventListener("online", function(e) {
      console.log("went online");
      console.log("event: ", e);
      deferred.resolve(navigator.onLine);
    }, false);
    window.addEventListener("offline", function(e) {
      console.log("went offline");
      console.log("event: ", e);
      deferred.resolve(!navigator.onLine);
    }, false);
  }
  return deferred.promise;
};

console.log('isOnline: ', monitorNow.isOnline());
console.log('isOffline: ', monitorNow.isOffline());
console.log('startWatching: ', monitorNow.startWatching());

return monitorNow;
};
ConnectivityMonitor.$inject = ['$rootScope', '$cordovaNetwork', '$q'];

1 个答案:

答案 0 :(得分:1)

你的代码对我来说看起来很复杂,也许你想看看demo app of mine,这几乎完全一样。它不是Ionic应用程序,而是Angular和TypeScript ......

首先,我构建了一个service来获取在线状态并将其存储在变量deviceIsOnline中。

class NetworkStatusService implements INetworkStatusService {
    deviceIsOnline: boolean;

    constructor() {
        document.addEventListener("deviceready", () => {
            if (navigator.connection.type === Connection.NONE) {
                this.deviceIsOnline = false;
            } else {
                this.deviceIsOnline = true;
            }
        });

        document.addEventListener("offline", () => {
            this.deviceIsOnline = false;
        });
        document.addEventListener("online", () => {
            this.deviceIsOnline = true;
        });
    }
}

我将此服务注入我的controller并使用deviceIsOnline变量。

class IndexController {
    static $inject = ["cordovaStarter.NetworkStatusService"];
    constructor(private networkStatusService: INetworkStatusService) {
    }

    showNetworkStatus(): void {
        if (this.networkStatusService.deviceIsOnline) {
            alert("Online");
        } else {
            alert("Offline");
        }
    }
}

在您的情况下,您可能需要watch deviceIsOnline变量,这样您就可以在每次变量更改时执行代码,而不是按下按钮点击... This可能有帮助了解手表模式,如果你还不知道;)

为了完整性,请注意我将我的实现隐藏在以下界面后面:

interface INetworkStatusService {
    deviceIsOnline: boolean;
}