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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12265565/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 15:45:01  来源:igfitidea点击:

AngularJS promise is resolved before data is loaded

javascriptajaxangularjs

提问by kshep92

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:

在我的应用程序中,我必须在页面加载之前获取一些 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; };
...
}

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();
}

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.

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

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 afterthe view is loaded.

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

How do I fix this?

我该如何解决?

回答by Gloopy

I haven't used resolvebut 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.

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

If you are returning your cardsarray 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).

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

Something like:

就像是:

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

See this fiddlefor 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.

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

The main difference between the two is:

两者的主要区别在于:

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


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

更新:此外,正如 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;
      },