使用$ interval对服务方法不起作用

时间:2015-04-14 11:57:06

标签: javascript angularjs web-applications

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

我使用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来调用它时才会出现问题。

由于

2 个答案:

答案 0 :(得分:2)

1)您的视图不会更新,因为您的$scope.online绑定到value,而不是reference(对象/数组/函数)。

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>

答案 1 :(得分:0)

我想建议使用拦截器。只是chceck如果它是正确的请求,如果它有正确的标头,设置好,如果它不是$injector放rootScope,或甚至广播此事件。然后像请求者一样使用服务

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