2014-12-09 99 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