2014-12-09 98 views
0

我有这样的服务:angularjs服务工作不正常

angular.module('autotestApp').factory('GroupService', ['$http', function ($http) { 
    var groups = []; 

    return{ 
     list: function() { 
      return groups; 
     }, 
     retrieve: function() { 
      $http({ 
       method: "get", 
       url: "/enterprises/_groups" 
      }).success(function (response) { 
       groups = response; 
      }).error(function() { 
       console.log("failed") 
      }); 
     } 
    } 
}]); 

,这是我的控制器:

angular.module('autotestApp').controller('GroupsController', function($scope, $http, GroupService) { 
    GroupService.retrieve(); 
    $scope.items = GroupService.list(); 
}); 

所以,在我的控制,我第一次收到来自API的结果使变量组(在服务中)被分配,然后我使用list()方法将值赋给$ scope.items。

我确定API正在返回结果。但是

groups = response 

部件无法正常工作。当我把它改成

groups.push(response) 

这是工作,但结果是一个列表内的列表,这是我想dont't:[对象,对象,对象]

我想这一点:[对象,对象,对象]

如何解决这个问题?

回答

1

原因

groups = response 

不工作是因为你发送一个异步请求,它将取代组引用您已经取回经list功能的旧引用后。它与push修改一起工作的原因是Angular创建了一个手表,注意到集合已更改并更新了您的视图。然而,你的代码现在正在工作,但你不明白它为什么会起作用,并且容易意外打破。

在处理异步代码时,处理它的最好方法是编写自己的代码来将其考虑在内。这是一个以异步方式完成整个事情的版本:

angular.module('autotestApp').factory('GroupService', ['$http', function ($http) { 
    var groupsResult; 

    return{ 
     retrieve: function() { 
      if (groupsResult) { return groupsResult; } 
      return groupsResult = $http({ 
       method: "get", 
       url: "/enterprises/_groups" 
      }).then(function (response) { 
       return response.data; 
      }, function() { 
       console.log("failed") 
      }); 
     } 
    } 
}]); 

angular.module('autotestApp').controller('GroupsController', 
    ['$scope', 'GroupService', function($scope, GroupService) { 
     GroupService.retrieve().then(function (groups) { 
      $scope.items = groups; 
     }); 
    }]); 
+0

这是工作:)但我需要该组变量分配给response.data,以便我可以在另一个控制器中使用它。但是,我没有提到在我的问题中,你的回答是正确的,所以我会接受它。 – Rodrigue 2014-12-09 13:33:00

+0

我编辑答案以添加响应的缓存,以便您可以在不同控制器中使用结果,但它只会发出单个请求。 – Rytmis 2014-12-09 19:32:40

1

一个你可以使用修复的是:

for (var i = 0; i < response.length; i++) { 
    groups.push(response[i]); 
}); 

这样,你将有[ Object, Object, Object ]

编辑:你可以尝试

一件事是下面的,改变你的检索函数返回您的承诺:

return{ 
      list: function() { 
       return groups; 
      }, 
      retrieve: function() { 
       var promise = $http({ 
        method: "get", 
        url: "/enterprises/_groups" 
       }).success(function (response) { 
        groups = response; 
       }).error(function() { 
        console.log("failed") 
       }); 

       return promise; 
      } 
     } 

,然后在你的控制器:

angular.module('autotestApp').controller('GroupsController', function($scope, $http, GroupService) { 
    GroupService.retrieve().finally(function() { 
     $scope.items = GroupService.list(); 
    }); 
}); 

我觉得你groups = response工作,但是当你做$scope.items = GroupService.list()请求尚未完成。

+0

是的,你是对的,但是当我有成千上万的结果来自api时,它会不会很贵?) – Rodrigue 2014-12-09 12:20:50

+0

我编辑了我的答案。 – 2014-12-09 12:28:18

+1

就性能而言,手动遍历列表而不是使用'angular.forEach'会更好。 'for(var i = 0; i GeoffreyB 2014-12-09 12:29:29

0

groups.concat(response) 这会使条款变平坦&将其添加到父列表而不是附加单个元素。

+0

不工作,我认为这是因为concat只适用于原始类型。在这里我得到对象 – Rodrigue 2014-12-09 12:23:01

+0

运行在节点REPL ::::: a = ['b','c','d'] ['b','c','d'] b = [Object (),Object(),Object()] [{},{},{}] > a.concat(b) ['b','c','d',{},{},{ }] – 2014-12-09 12:25:13