在服务方法上使用 $interval 不起作用

Use $interval on a service method isn't working

我正在构建一个移动网络应用程序,用于检测用户浏览器是否可以访问互联网。

我正在使用 AngularJS 框架来实现这一点。我每 1000 毫秒从 AppData 调用一个服务方法来测试用户与 ajax 请求的连接。

PicController 将结果绑定到我的 html 视图。

我的想法是创建一个服务 AppData,它将存储我的应用程序的一般属性和方法。

这段代码根本行不通,我猜是方法不对,有高手能告诉我怎么做吗?

错误:

TypeError: Cannot read property 'online' of undefined
    at isOnline (pictureViewer.js:24)

代码:

'use strict';

var picApp = angular.module('pictureViewerApp',[]);

picApp.run(['$interval','AppData', function($interval, AppData){
    $interval(AppData.isOnline,1000);
}]);

picApp.controller("PicController",['$scope', 'AppData', function($scope, AppData){
    $scope.online = AppData.online;
}]);

picApp.factory('AppData', ['$http', function($http) {
    var AppData = {};
    AppData.online = false;
    AppData.isOnline = function() {
        var appData = this;
        $http.get('online.php').
            success(function(data) {
                appData.online = true;
            }).
            error(function() {
                appData.online = false;
            });
        console.log("AppData.online = ", appData.online);
    };
    return AppData;
}]);

编辑: 错误恰好发生在这一行:

console.log("AppData.online = ", appData.online);

编辑 2: 如果我调用我的方法一次它工作正常,只有当我使用 $interval 调用它时才会出现问题。

谢谢

1) 您的视图不会更新,因为您的 $scope.online 绑定到 value,而不是 reference (object/array/function)。

2) 不使用 bind 就不能将 ´AppData.isOnline´ 作为参数传递(检查浏览器兼容性) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

检查这个工作示例:

var picApp = angular.module('pictureViewerApp',[]);

picApp.run(function(AppData, $interval) {
  $interval(AppData.isOnline.bind(AppData), 1000);
  /*
  //Is same as
  $interval(function(){
    AppData.isOnline();
  }, 1000);*/
});

picApp.controller("PicController",['$scope', 'AppData', function($scope, AppData){
    $scope.AppData = AppData;
}]);

picApp.factory('AppData', function($q) {
    var AppData = {
      online: false
      
    };
    
    AppData.isOnline = function() {      
      var deferred = $q.defer();
      
      // TODO: Use $http to load.
      this.online = true;
      deferred.resolve(true);
      
      return deferred.promise;
    };
  
    
    return AppData;
});
<!DOCTYPE html>
<html ng-app="pictureViewerApp">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script data-require="angular.js@1.4.x" src="https://code.angularjs.org/1.4.0-rc.0/angular.js" data-semver="1.4.0-rc.0"></script>
  </head>

  <body ng-controller="PicController">
    <p>User is online? {{AppData.online}}!</p>
  </body>

</html>

我建议使用拦截器。只是检查它是否是正确的请求,如果它得到正确的 header,设置 ok,如果它不是 thur $injector 放置 rootScope,甚至广播这个事件。然后像请求者一样使用服务

picApp.service('AppData', function($http) {
    this.getOnlineResponse = function(){
        $http(someApiRequestPath);
       }
     return this;
});