【问题标题】:AngularJS - When does a service retrieve data?AngularJS - 服务何时检索数据?
【发布时间】:2014-04-12 23:01:03
【问题描述】:

服务/工厂何时从 HTTP 请求中检索数据?

在服务中创建工厂时,我很好奇HTTP请求是什么时候发送的,以及应用运行一段时间后是如何处理的。

我正在使用Ionic Framework 编写我的代码。一旦我初始化我的应用程序,并且它保持打开一两天,JSON 数据会以任何间隔刷新吗?还是只有在应用关闭后才刷新数据,然后再次打开?

我对 HTTP 请求的要求是每天早上 00:01 更新。

我想我的一般问题是:HTTP 请求如何获取数据?以及服务如何在 AngularJS 中工作。

这是我检索 JSON 包的代码:

angular.module('starter.services', [])

.factory('menuJSON', function ($http) {

   return {
     all : function() {
       return $http({
         url: 'http://middmenuapi.herokuapp.com/',
         method: 'GET'
       })
     }
   }
});

【问题讨论】:

  • 为什么人们不赞成这个问题?这对我来说似乎有效且重要
  • 我没有投反对票,但我想这是因为您的问题表明您不了解 http(此处为 ajax)和角度服务背后的一般机制。有很多资源可以彻底解释这两个不同且不相关的主题。 http 是一个更深层次的主题,但对于角度服务,我向您推荐这个docs.angularjs.org/guide/concepts#service

标签: angularjs angularjs-service angularjs-factory ionic-framework


【解决方案1】:

调用$http()(或任何别名,例如$http.get() 等)会立即调用网络请求(除非检查员或第三方组件进行任何操作)。它类似于在其他框架(如 jQuery)中发出 XmlHttpRequest 或 JSONP 请求。

服务被创建为单例,因此它们在第一次被请求时创建一次,并且从那时起注入相同的实例。该服务的作用完全取决于您,因为 Angular 只处理实例化它、解析它的任何依赖项并将其注入到任何需要它的地方。

如果您的应用程序需要长时间运行并需要使用数据进行更新,则您需要对其进行适当的架构设计。显然,我不知道您的规范的全部要求或细节,但我可以给您一些提示,也许可以帮助您。

高级,听起来你需要一个函数来操作一个定时器(使用$timeout服务),如果你达到或超过一个时间窗口,调用一个$http请求来检索最新的数据和路由它以及需要它的各种组件。然后,它应该标记下一次操作的时间范围,然后再次设置超时,以便它可以在更远的地方醒来,看看是否是时候再次工作了。

首先要考虑的是这个功能应该放在哪里?如果您只需要它发生在某个控制器中,那么您可以使用$timeout$http 在该控制器中完成所有操作。另一方面,如果您需要在多个地方重用这些数据,您将需要使用服务。如果您很可能使用某项服务,那么您需要找出将这些更改应用到需要它的各个部分的最佳方法。

我的建议是当您的 $http 请求更新数据时,在您的服务中使用 $rootScope$broadcast 上的 Angular 事件。然后,使用此数据的各种控制器、服务和指令可以使用 $scope.$on 订阅此事件并做出适当的反应。这使服务与使用它的事物分离,并允许它们轻松地对更改做出反应。

服务所做的只是设置一个超时,当它失效时检查数据,如果它有数据,在$rootScope上的一个事件中广播数据,并设置另一个超时。客户端在接收到来自服务的事件时,只会监听并使用新数据更新其本地范围。

This 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
    }]);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-17
    • 1970-01-01
    • 2018-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-15
    相关资源
    最近更新 更多