[英]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"
});
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.