Angular Best Practice:服务启动时的数据

时间:2014-09-21 01:50:08

标签: angularjs

我想创建一个角度服务,在“启动”时抓取数据并构建一个在应用程序生命周期内不会改变的数组。我不想返回http请求的承诺。缓存结果仍然会导致'someExpensiveFunctionCall'的成本。处理这种情况的最佳方法是什么,可以保证服务将填充结果,并可以在控制器和/或其他服务中使用。

angular.module('app')
.service('MyService', function($http, defaults) {
  var result = [];
  $http.get('/some/url').then(function(data) {
    if(angular.isDefined(data)) {
      _.forEach(data, function(item) {
        result.push(someExpensiveFunctionCall(item.value));
      });
    } else {
      result = angular.copy(defaults.defaultResult);
    }
  });
  return {
    result: result
  };
})
.controller(function(MyService) {
  var someData = MyService.result;
})
.service(function(MyService) {
  var someData = MyService.result;
});

1 个答案:

答案 0 :(得分:1)

  

我不想退回http请求的承诺。

好像你想要做一些异步的事情;同步。如果没有某种回调,承诺,同步XHR或其他机制,这将无法正常工作。

知道我们可以评估一些选项。 (按照最实际的顺序)

  1. 使用路由器resolve属性。这将在实例化控制器之前完成一些承诺返回操作。它(在ui-routerngRoute中)表示承诺的结果将以指定的密钥名称注入控制器。

  2. 使用承诺。

  3. (手动称为#1)

    .factory('MyService',function($http,defaults){
        var ret = {result: []}; 
        ret.promise = $http.get('url').then(function(data){
            if(angular.isDefined(data)){
                _.forEach(data,function(item){
                    ret.result.push(someExpensiveFunctionCall(item.value));
                });
            }else{
                _.forEach(angular.copy(defaults.defaultResult),function(val){
                    ret.result.push(val);    
                });
            }
            return ret;
        });        
        return ret;
    })
    .controller('MyCtrl',function(MyService){
        MyService.promise.then(myCtrl);
        function myCtrl(){
            var result = MyService.result
        }
    })
    
    1. 懒惰的评价。 - >由于脏检查,这个角度有点慢。但实质上意味着你不能立即操纵/阅读控制器或服务体内的result。但是,使用视图绑定,过滤器和交互来调用作用于数据的作用域函数。由于promise的解析将调用摘要周期。数据到达时,您的视图将呈现。
    2. 如果data恰好未定义,则代码中存在错误。您通过将其设置为默认值的副本来取消引用result。 所以对MyService.result的所有引用都将是一个空数组,而不是默认值。 为了保持引用,我会循环使用默认值,并使用result将其添加到result.push

      希望这有帮助!