简体   繁体   English

AngularJS在$ interval上轮询$ resource不会自动解决从$ resource返回的承诺

[英]AngularJS polling a $resource on an $interval doesn't automagically resolve the promise returned from $resource

So, the important bits: When I bind a $scope variable in my controller directly to a $resource, angular's automatic promise resolution takes over and my view gets updated as soon as data comes back from the service. 因此,重要的一点是:当我将控制器中的$ scope变量直接绑定到$ resource时,angular的自动promise解析将接管工作,并且一旦从服务返回数据,我的视图就会更新。 However, I need to poll the server for updates on an interval. 但是,我需要定期轮询服务器以获取更新。 Attempting to bind to the promise returned from the $interval call is not triggering angular's automatic promise resolution and I do not know if there is something that can be done to get this $interval working against a $resource. 尝试绑定到$ interval调用返回的promise不会触发angular的自动promise解析,而且我不知道是否可以做一些事情来使此$ interval与$ resource一起工作。

Angular client, ASP.NET WebApi serving JSON, Angular $resource sitting over WebApi. Angular客户端,ASP.NET WebApi提供JSON,Angular $ resource位于WebApi上。 Inside my angular controller, if I bind a $scoped variable to my $resource promises directly, I get results; 在我的角度控制器内部,如果我直接将$ scoped变量绑定到$ resource promises,则会得到结果; however, I need my $resources to update on an $interval and I am having problems introducing the interval. 但是,我需要我的$ resources在$ interval上进行更新,并且在引入间隔时遇到了问题。

The working, "needs manual refreshing" code (the relevant part, at least) 正常的“需要手动刷新”代码(至少是相关部分)

'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 in my view bound to "bar in Bars" = data to screen. 等等等等,在我看来,ng-repeat绑定到“ bar in Bars” =要筛选的数据。

So now, I go into my controller to implement my interval, and I can get the interval working but the promise does not resolve. 所以现在,我进入控制器来实现我的间隔,我可以使间隔正常运行,但诺言无法解决。

The changes inside the controller (note that I added $interval and $document to my dependency list: 控制器内部的更改(请注意,我在依赖列表中添加了$ 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"
});

Edit 编辑

Note that the problem I am having is that binding $scope.Bars directly to service.Bars triggers angular's automatic promise resolution but introducing the $interval call does not seem to be. 请注意,我遇到的问题是将$ scope.Bars直接绑定到service.Bars会触发angular的自动promise解析,但是引入$ interval调用似乎并非如此。 Inspecting $scope.Bars in Chrome Dev Tools indicates that it is an unresolved promise. 在Chrome开发工具中检查$ scope.Bars表示这是一个未解决的承诺。

I updated my sample code to match what I currently have in my debugger. 我更新了示例代码以使其与调试器中当前的代码匹配。 I have several properties defined on my resource, and I included one that I named 'Baz'. 我在资源上定义了几个属性,并且包括一个名为“ Baz”的属性。 If I assign $scope.Baz = service.Baz directly within my controller, the view binds to it when angular resolves the promise but the one on the interval never does. 如果我直接在我的控制器内分配$ scope.Baz = service.Baz,则当angular解析promise时,视图将绑定到该视图,但是间隔上的那个则永远不会。

You aren't returning the promise from $scope.pollService . 您不会从$scope.pollService返回promise Just add return stop; 只需添加return stop; at the end of your function. 在您的功能结束时。 Also note that the way your API is written, your function will still return undefined if stop is defined. 还要注意,编写API的方式是,如果定义了stop ,函数仍将返回undefined

Therefore, it should probably look like: 因此,它可能看起来像:

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

  return stop;
};

stop is also not a very good descriptive name... stop也不是一个很好的描述性名称...

EDIT: 编辑:

From my understanding after reading the docs, you should be invoking the action method on the service like $scope.Bars = service.Bars(); 根据我阅读文档的理解,您应该在$scope.Bars = service.Bars();等服务上调用action方法$scope.Bars = service.Bars(); . This will return an object that will eventually get populated with data once the promise is resolved. 这将返回一个对象,一旦解决了诺言,该对象最终将填充数据。 However, I think you also need to be careful here, because if the interval fires faster than the promise resolving rate you might run into issues. 但是,我认为您在这里还需要格外小心,因为如果间隔触发的速度快于承诺解决率,那么您可能会遇到问题。 I think that you would be better off using $timeout . 我认为使用$timeout会更好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM