调用$http()
(或任何别名,例如$http.get()
等)会立即调用 Web 请求(除非检查员或第三方组件进行任何操作)。它类似于在其他框架(如 jQuery)中发出 XmlHttpRequest 或 JSONP 请求。
服务被创建为单例,因此它们在第一次被请求时创建一次,并且从那时起注入相同的实例。该服务的功能完全取决于您,因为 Angular 只处理实例化它、解决它的任何依赖项以及将它注入到任何需要它的地方。
如果您有一个长时间运行的应用程序并且需要使用数据进行更新,那么您需要对其进行适当的架构设计。显然我不知道你的规格的全部要求或细节,但我可以给你一些提示,也许会让你继续前进。
高级别的,听起来您需要一个函数来操作计时器(使用$timeout
服务),如果您达到或超过时间窗口,请调用$http
请求以检索最新数据并将其路由到需要它的各个组件。然后,它应该标记下一次操作的时间范围,然后再次设置超时,以便它可以在更远的地方醒来,看看是否是时候再次工作了。
首先要考虑的是这个功能应该放在哪里?如果您只需要它在某个控制器中发生,那么您可以在该控制器中使用$timeout
and完成所有操作$http
。另一方面,如果您需要在多个地方重用这些数据,您将需要使用服务。如果您很可能使用服务,那么您需要找出最好的方法来将这些更改用于需要它的应用程序的各个部分。
我的建议是当您的请求更新数据时$rootScope
,$broadcast
在您的服务中使用 Angular 事件。$http
然后,使用此数据的各种控制器、服务和指令可以订阅此事件$scope.$on
并做出适当的反应。这使服务与使用它的事物脱钩,并允许它们轻松地对更改做出反应。
服务所做的只是设置一个超时,当它失效时检查数据,如果它有数据,在事件中广播数据$rootScope
,并设置另一个超时。当客户端从服务接收到事件时,它只会监听并使用新数据更新其本地范围。
这个 plunk包含一个愚蠢的例子。您可能希望将其更改为在一天中的某个时间或您认为合适的任何时间安排工作,然后让它发出$http
请求而不是发送当前日期。
angular.module("demo", [])
.service('myService', ['$rootScope', '$timeout', '$http', function($rootScope, $timeout, $http) {
var state = { timeout: null, next: null };
function work() {
var now = Date.now();
if (now >= state.next) { // you can replace with your own logic to schedule when it should occur (like a specific time of day). in this example, we poll every second, but do work every 5.
// this is where your $http service can do work, something like $http.get(...).success(function(data) { $rootScope.$broadcast('myService.data', data); });
$rootScope.$broadcast('myService.data', new Date());
state.next = now + 5000; // do work every five seconds
}
state.timeout = $timeout(work, 1000); // poll every second
}
return {
start: function() {
if (state.timeout) $timeout.cancel(state.timeout); // cancel pending timeout
work(); // first time will just schedule work to be done in the future
},
stop: function() {
if (state.timeout) $timeout.cancel(state.timeout); // cancel pending timeout
}
};
}])
.controller('DemoCtrl', ['$scope', function($scope) {
$scope.title = "Hello, World";
// here, the controller subscribes to the event, and when it occurs, it copies the event data to a local scope item
$scope.$on('myService.data', function(evt, data) {
$scope.$apply(function() {
$scope.myServiceData = data;
});
});
}])
.run(['myService', function(myService) {
myService.start(); // starts the service when the app runs
}]);