AngularJS全球http轮询服务

ssl*_*ian 34 javascript angularjs

我正在使用AngularJS构建一个Web应用程序.该应用程序需要轮询一个返回JSON数据的URL,并将该数据提供给应用程序的任何部分.从我到目前为止所读到的内容来看,我最好的办法是创建一个处理轮询并保留其自己的JSON数据内部缓存的服务,然后将服务注入到想要查询该数据的应用程序的任何部分.我迷失的是如何实际去做.我发现的最接近的例子是这个问题,但它似乎是创建一个由特定控制器手动调用的服务(它本身与给定路由绑定),而我想要在应用程序的后台持续运行的东西永远不管应用程序的哪个部分是活跃的.这是可行的,还是我采取了完全错误的做法?

Val*_*nov 42

我的解决方案:

app.factory('Poller', function($http, $timeout) {
  var data = { response: {}, calls: 0 };
  var poller = function() {
    $http.get('data.json').then(function(r) {
      data.response = r.data;
      data.calls++;
      $timeout(poller, 1000);
    });      
  };
  poller();

  return {
    data: data
  };
});
Run Code Online (Sandbox Code Playgroud)

(调用只是为了表明已完成投票)

http://plnkr.co/edit/iMmhXTYweN4IrRrrpvMq?p=preview

编辑:正如Josh David Miller在评论中建议的那样,应该在app.run块中添加对此服务的依赖,以确保从开始执行轮询:

app.run(function(Poller) {});
Run Code Online (Sandbox Code Playgroud)

并且还在上次调用完成后移动了下一轮询的调度.因此,如果轮询长时间挂起,则不会"堆叠"呼叫.

更新了plunker.

  • +1但是他想要总是运行的东西,所以也从`app.run`块触发它以确保它从一开始就运行.我还要检查`poller`函数以确保先前调用`$ http`已完成,这样它们就不会无休止地堆叠,但似乎没有办法用AngularJS promise实现. (2认同)

小智 21

这是Github上的一个角度轮询器服务,可以很容易地注入到你的控制器中.

安装: bower install angular-poller.

由于您要启动永久在后台运行的全局轮询​​服务,您可以执行以下操作:

// Inject angular poller service.
var myModule = angular.module('myApp', ['poller']);

// The home/init controller when you start the app.
myModule.controller('myController', function($scope, $resource, poller) {

    // Define your resource object.
    var myResource = $resource(url[, paramDefaults]);

    // Create and start poller.
    var myPoller = poller.get(myResource);

    // Update view. Most likely you only need to define notifyCallback.
    myPoller.promise.then(successCallback, errorCallback, notifyCallback);
});
Run Code Online (Sandbox Code Playgroud)

现在它将永远在后台运行,直到你打电话myPoller.stop()poller.stopAll().

如果要在其他控制器中使用此轮询器的回调数据,则可以执行以下操作:

myModule.controller('anotherController', function($scope, $resource, poller) {

    /* 
     * You can also move this to a $resource factory and inject it
     * into the controller so you do not have to define it twice.
     */
    var sameResource = $resource(url[, paramDefaults]);

    /* 
     * This will not create a new poller for the same resource
     * since it already exists, but will simply restarts it.
     */
    var samePoller = poller.get(sameResource);

    samePoller.promise.then(successCallback, errorCallback, notifyCallback);
});
Run Code Online (Sandbox Code Playgroud)