AngularJS 承诺在数据加载之前解决 [英] AngularJS promise is resolved before data is loaded

查看:29
本文介绍了AngularJS 承诺在数据加载之前解决的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In my app, I have to fetch some JSON data and assign it to an array before the page is loaded. This is my code for fetching the JSON using the CardService service:

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

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

In the controller's resolve block, I have the following:

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

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

And in the actual controller, I have the following:

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

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

The problem is, the fetchCards function in the service seems to resolve the promise before the JSON data is assigned to the cards variable. This leads to my view loading with blank data until I refresh a couple times and get lucky.

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

I can confirm the late loading as when I log the cards variable in the console, I get an empty array at line 122 (when my view is loaded) and a full array at line 57 (when the JSON call is successful). Line 57's code somehow executes after the view is loaded.

我该如何解决这个问题?

How do I fix this?

推荐答案

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

I haven't used resolve but I'm throwing this out there just in case the issue you are having is related to binding to an array returned from a service.

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

If you are returning your cards array from a service and binding to it in the UI you may want to try to populate that same array instead of setting cards = data; (which will overwrite the local cards with a new array which is not bound to the 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;
      },

请参阅 this fiddle 以了解我要描述的工作示例.多次单击第一个按钮将更新视图,但一旦单击第二个按钮,绑定将被破坏.

See this fiddle for a working example of what I'm trying to describe. Clicking the first button multiple times will update the view but once you click on the second button the binding will be broken.

两者的主要区别在于:

  1. 第一个按钮使用data.length = 0data.push() 来保留原始数组的引用
  2. 第二个按钮使用 data = newArray
  3. 用新的数组引用覆盖原始的 data 数组引用
  1. First button uses data.length = 0 and data.push() to retain the original array's reference
  2. Second button overwrites the original data array reference with a new one using data = newArray

<小时>

更新:另外,作为 Mark Rajcok,下面提到你可以使用 angular.copy 通过清空原始数组并从源添加新数组来保留原始数组的引用,如下所示:


Update: Also, as Mark Rajcok, mentioned below you can use angular.copy to retain the original array's reference by emptying it out and adding new ones from the source like this:

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;
      },

这篇关于AngularJS 承诺在数据加载之前解决的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆