9

在我的应用程序中,我必须在页面加载之前获取一些 JSON 数据并将其分配给一个数组。这是我使用 CardService 服务获取 JSON 的代码:

cards = [];

var cs = {
...
fetchCards: function() {
      var d = $q.defer();
      $http.get("data/cards.php").success(function(data) {
                      cards = data;
                      d.resolve();
                }).error(function(data, status) {
                      d.reject(status);        
                 });
               return d.promise;
      },
getCards: function() { return cards; };
...
}

在控制器的解析块中,我有以下内容:

WalletController.resolve = {
        getCards: function(CardService) {
                CardService.fetchCards().then(loadView, showError);
        }
}

在实际控制器中,我有以下内容:

function WalletController($scope, CardService) {
    $scope.cards = CardService.getCards();
}

问题是,服务中的 fetchCards 函数似乎在将 JSON 数据分配给卡变量之前解决了承诺。这导致我的视​​图加载空白数据,直到我刷新几次并走运。

我可以确认延迟加载,因为当我在控制台中记录卡变量时,我在第 122 行(加载我的视图时)得到一个空数组,在第 57 行(当 JSON 调用成功时)得到一个完整数组。第 57 行的代码在视图加载后以某种方式执行。

我该如何解决?

4

1 回答 1

16

我没有使用过resolve,但我把它扔在那里以防万一您遇到的问题与绑定到从服务返回的数组有关。

如果您cards从服务返回数组并在 UI 中绑定到它,您可能希望尝试填充相同的数组而不是设置cards = data;(这将使用未绑定到 UI 的新数组覆盖本地卡片)。

就像是:

fetchCards: function() {
      var d = $q.defer();
      $http.get("data/cards.php").success(function(data) {
                      cards.length = 0;
                      for(var i = 0; i < data.length; i++){
                          cards.push(data[i]);
                      }
                      d.resolve();
                }).error(function(data, status) {
                      d.reject(status);        
                 });
               return d.promise;
      },

请参阅此小提琴以获取我要描述的工作示例。多次单击第一个按钮将更新视图,但是一旦单击第二个按钮,绑定将被破坏。

两者的主要区别在于:

  1. 第一个按钮使用data.length = 0data.push()保留原始数组的引用
  2. data第二个按钮使用新的数组引用覆盖原始数组引用data = newArray

更新:另外,正如下面提到的 Mark Rajcok,您可以使用angular.copy来保留原始数组的引用,方法是清空它并从源中添加新的引用,如下所示:

fetchCards: function() {
      var d = $q.defer();
      $http.get("data/cards.php").success(function(data) {
                      angular.copy(data, cards);
                      d.resolve();
                }).error(function(data, status) {
                      d.reject(status);        
                 });
               return d.promise;
      },
于 2012-09-05T18:11:35.887 回答