Angularjs 角度最佳实践:服务启动时的数据

Angularjs 角度最佳实践:服务启动时的数据,angularjs,Angularjs,我想创建一个角度服务,它在“启动”时捕获数据,并构建一个在应用程序生命周期内不会改变的阵列。我不想返回http请求的承诺。缓存结果仍然会产生“someExpensiveFunctionCall”的成本。处理这种情况的最佳方法是什么,以确保服务将填充结果,并可在控制器和/或其他服务中使用 angular.module('app') .service('MyService', function($http, defaults) { var result = []; $http.get('/s

我想创建一个角度服务,它在“启动”时捕获数据,并构建一个在应用程序生命周期内不会改变的阵列。我不想返回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;
});
我不想返回http请求的承诺

看起来你想做一些异步的事情;同步地。如果没有某种回调、承诺、同步XHR或其他机制,这将无法(可靠地)工作

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

  • 使用路由器
    resolve
    属性。这将在实例化控制器之前完成一些承诺返回操作。它还(在
    ui-router
    ngRoute
    中)意味着承诺的结果将以指定的密钥名称注入控制器

  • 履行诺言

  • (aka#1手动)

  • 惰性评估。-->由于脏检查,角度有点慢。但本质上意味着您不会立即在控制器或服务的主体内操纵/读取
    结果。而是使用视图绑定、过滤器和交互来调用作用于数据的范围函数。因为承诺的解决将调用一个摘要循环。当数据到达时,视图将呈现
  • 如果
    数据
    恰好未定义,则代码中存在错误。通过将
    结果设置为默认值的副本,可以取消引用该结果。
    因此,对
    MyService.result
    的所有引用将始终是一个空数组,而不是默认值。 为了维护引用,我将循环默认值,并使用
    result.push将它们添加到
    result

    希望这有帮助

    .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
        }
    })