【问题标题】:AngularJS polling a $resource on an $interval doesn't automagically resolve the promise returned from $resourceAngularJS 在 $interval 上轮询 $resource 不会自动解决从 $resource 返回的承诺
【发布时间】:2014-09-03 21:48:48
【问题描述】:

所以,重要的部分: 当我将控制器中的 $scope 变量直接绑定到 $resource 时,Angular 的自动承诺解析会接管,并且一旦从服务返回数据,我的视图就会更新。但是,我需要定期轮询服务器以获取更新。尝试绑定到从 $interval 调用返回的承诺不会触发 Angular 的自动承诺解决方案,我不知道是否可以做一些事情来让这个 $interval 对 $resource 起作用。

Angular 客户端,提供 JSON 的 ASP.NET WebApi,位于 WebApi 之上的 Angular $resource。在我的角度控制器中,如果我将 $scoped 变量直接绑定到我的 $resource 承诺,我会得到结果;但是,我需要我的 $resources 在 $interval 上更新,我在引入间隔时遇到了问题。

“需要手动刷新”的工作代码(至少是相关部分)

'use strict';
var ctrls = angular.module('MyModule',[]);
ctrls.controller('FooCtrl', ['$scope', '$location','service',
  function( $scope,$location,service)
  {
     $scope.Bars = service.Bars;
     $scope.Baz = service.Baz;
  }

var app = angular.module('MyModule.Services',['ngResource']);
app.service('service', ['$resource', function($resource)
{
  var proxy = $resource(
       'http://server/subsystem/api/Foo/:component',
        {},
        {
           Bars: {method:'GET',isArray:false,url: 'http://server/subsystem/api/Foo/Bars'
          ,Baz: {method:'GET',isArray:false,rul: 'http://server/subsystem/api/Foo/Baz'
        }
  return proxy;
}]);

blah blah blah,在我看来,ng-repeat 绑定到“bar in Bars”=要筛选的数据。

所以现在,我进入我的控制器来实现我的间隔,我可以让间隔工作,但承诺没有解决。

控制器内部的变化(注意我在依赖列表中添加了 $interval 和 $document:

var stop;
$scope.Bars = {};
$scope.Baz = service.Baz; //Note that angular resolves this promise automatically.
$scope.pollService = function(){
   if(angular.isDefined(stop))return;
   stop = $interval(function(){
     if(service){
        $scope.Bars = service.Bars;
     }
   },1000);
};
$scope.stopPolling = function(){
   if(angular.isDefined(stop)){
     $interval.cancel(stop);
     stop = undefined;
   }
};
$scope.$on('$destroy',function(){
   $scope.stopPolling();
});
$document.ready(function(){
   $scope.pollService(); //when I attempt to execute my .then() on pollService(), I get "cannot 
                         //call then on undefined"
});

编辑

请注意,我遇到的问题是将 $scope.Bars 直接绑定到 service.Bars 会触发 Angular 的自动承诺解决方案,但似乎没有引入 $interval 调用。在 Chrome 开发工具中检查 $scope.Bars 表明它是一个未解决的承诺。

我更新了我的示例代码以匹配我当前在调试器中的内容。我在我的资源上定义了几个属性,其中包括一个我命名为“Baz”的属性。如果我直接在我的控制器中分配 $scope.Baz = service.Baz ,则视图会在 Angular 解决承诺时绑定到它,但间隔上的承诺永远不会。

【问题讨论】:

  • 转录我的代码时出错。我会清理的

标签: javascript angularjs angular-resource angular-promise


【解决方案1】:

您没有从$scope.pollService 返回promise。只需在函数末尾添加return stop;。另请注意,您的 API 编写方式,如果定义了 stop,您的函数仍将返回 undefined。

因此,它应该看起来像:

$scope.pollService = function(){
   if(!angular.isDefined(stop)) {
       stop = $interval(function() {
         if(service){
            $scope.Bars = service.Bars;
         }
       }, 1000);
  }

  return stop;
};

stop 也不是一个很好的描述性名称...

编辑:

根据我阅读文档后的理解,您应该在服务上调用操作方法,例如$scope.Bars = service.Bars();。这将返回一个对象,一旦 promise 得到解决,该对象最终将填充数据。但是,我认为您在这里也需要小心,因为如果间隔触发速度快于承诺解决率,您可能会遇到问题。我认为你最好使用$timeout。

【讨论】:

  • 它是直接从 $interval 的角度文档中提取的。我现在只是想让它发挥作用。此外,返回 "stop" 并不能解决承诺;我希望就是这样:P
  • @K.AlanBates $interval 确实返回了文档所述的承诺。如果您正确地从$scope.pollService 返回,那么您应该可以执行$scope.pollService().then(...)。如果这不起作用,那么您的代码中还有另一个问题。
  • 我从$scope.pollService 和$scope.pollService().then(function...) 返回站永远不会触发。我在成功回调中设置了一个断点,在错误回调中设置了一个。我已经知道 $interval 返回了一个承诺。现在的问题(一如既往)是为什么将 $scope.Bars 直接绑定到 service.Bars 会触发 Angular 的自动承诺解决方案,但引入间隔却不会。如果我从间隔中解开服务调用并设置$scope.Bars = service.Bars,我的视图中的绑定控件将显示来自 service.Bars 的数据。
  • @K.AlanBates 好吧,这不是你的问题所说的。你说你收到cannot call then on undefined。无论如何,您是否检查过回调函数本身是否被调用?与其设置断点,不如将debugger; 语句放在你希望它中断的代码中,这样更可信。
  • 关于 pollService.then 在我的代码块中的评论是旁白。我曾 尝试 在 $document.ready 中调用 pollService.then ,但没有解决。添加 return stop 解决了这个(相当小的)问题,但问题是通过 $interval 从服务中返回 Bars 不会触发 Angular 的自动承诺解决
猜你喜欢
  • 2018-03-15
  • 1970-01-01
  • 2015-06-20
  • 2014-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-24
  • 1970-01-01
相关资源
最近更新 更多