AngularJS承诺在加载数据之前得到解决

ksh*_*p92 9 javascript ajax angularjs

在我的应用程序中,我必须获取一些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; };
...
}
Run Code Online (Sandbox Code Playgroud)

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

WalletController.resolve = {
        getCards: function(CardService) {
                CardService.fetchCards().then(loadView, showError);
        }
}
Run Code Online (Sandbox Code Playgroud)

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

function WalletController($scope, CardService) {
    $scope.cards = CardService.getCards();
}
Run Code Online (Sandbox Code Playgroud)

问题是,服务中的fetchCards函数似乎在将JSON数据分配给cards变量之前解析了promise.这导致我的视​​图加载空白数据,直到我刷新几次并获得幸运.

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

我该如何解决?

Glo*_*opy 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;
      },
Run Code Online (Sandbox Code Playgroud)

请看这个小提琴,找一个我想要描述的实例.多次单击第一个按钮将更新视图,但是一旦单击第二个按钮,绑定将被破坏.

两者的主要区别是:

  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;
      },
Run Code Online (Sandbox Code Playgroud)

  • 我不是同性恋,但我现在可以亲你!这解决了一切.谢谢你! (5认同)
  • `angular.copy(data,cards)`也可以.当目标提供给[copy()](http://docs.angularjs.org/api/angular.copy)方法时,它将首先删除目标的元素,然后从源中复制新的元素. (5认同)