【问题标题】:Loading asynchronous data in AngularJS在 AngularJS 中加载异步数据
【发布时间】:2016-08-21 14:57:54
【问题描述】:

我在调用函数时收到Cannot read property of undefined 错误,但数据显示正确。

根据我目前阅读的内容,这是因为 AngularJS 异步加载数据,我应该使用 Promise 来避免这种情况。

我在网上搜索过 Angular 的文档,但我不明白如何使用它。

如果有人可以帮助我,我将不胜感激。

目前,我有以下代码:

.factory('Test', ['$resource', function ($resource) {
  return $resource('data.json');
}])

.controller('MyCtrl', ['$scope', 'Test', function($scope, Test) {

Test.get(function (data) {
  $scope.myData = data;
});

$scope.myFunction = function() {
  var min = $scope.myData.min;
  var max = $scope.myData.max;
  var diff = max - min;
  return diff;
}

}])

这是一个 Plunker:http://plnkr.co/edit/3AK70uVbNSdhAIIfdkHb?p=preview

【问题讨论】:

    标签: javascript angularjs asynchronous promise angular-promise


    【解决方案1】:

    只需定义$scope.myData = {}

    例如为您的代码:

    angular.module('myApp', ['ngResource'])
    
    .factory('Test', ['$resource', function ($resource) {
      return $resource('data.json');
    }])
    
    .controller('MyCtrl', ['$scope', 'Test', function($scope, Test) {
      $scope.myData = {}  // <--- That's what I have defined
      Test.get(function (data) {
          $scope.myData = data;
      });
    
      $scope.myFunction = function() {
          var min = $scope.myData.min;
        var max = $scope.myData.max;
        var diff = max - min;
        return diff;
      }
    
    }])
    

    【讨论】:

      【解决方案2】:

      在填充$scope.myData 之前,您不应使用$scope.myData.min,正如您所说的那样,它是异步的,因此可能需要一点时间。在这种情况下,最简单的解决方案是将您的代码包装到 if-block 中:

      $scope.myFunction = function() {
        if ($scope.myData) {
          var min = $scope.myData.min;
          var max = $scope.myData.max;
          var diff = max - min;
          return diff;
        }
      }
      

      myFunction 将在每个摘要周期中检查,因此一旦 $scope.myData 可用,该函数将评估并正确返回 diff。

      然而,更好的方法是使用资源返回的promise 对象。在这种情况下,您可以执行以下操作:

      function myFunction(myData) {
        var min = myData.min;
        var max = myData.max;
        var diff = max - min;
        return diff;
      }
      
      Test.get().$promise.then(myFunction).then(function(data) {
        $scope.myData = data;
      });
      

      在 HTML 中使用 myData 而不使用函数:

      <div ng-controller="MyCtrl">
        {{myData}}
      </div>
      

      演示: http://plnkr.co/edit/2SSk2lChkbvm5ffbHF2n?p=preview

      【讨论】:

      • 我只是在想:如果我想将值传递给函数怎么办(例如{{myData(2)}} 其中2 将是min。然后,我将无法使用第二种方法,对吗?
      • 那你就不能用了,是的。但是,我不建议使用这样的函数,该函数将被多次调用,可能会出现性能问题。最好设置范围属性并在 myFunction 中使用它。
      • 我明白了。但是假设我想要这样的东西:plnkr.co/edit/9qv6cXs1RaOOaxhJ3U1X?p=preview - 那么,有没有比使用这样的函数更好的方法?
      • 实际上,我对上面的代码 (plnkr.co/edit/Bi17ENfKoAelqgihEeQs?p=preview) 做了一些更改,但我想知道将计算直接放入 HTML 而不是为其编写函数是否是一种好习惯。
      • 是的,这种情况下简单计算就可以了。
      【解决方案3】:

      您的代码很好,可能需要稍作修改以避免

      无法读取未定义错误的属性

      $scope.myData = Test.get();
      

      那么你可以拥有

      $scope.myFunction = function() {
          var min = $scope.myData.min;
          var max = $scope.myData.max;
          var diff = max - min;
          return diff || 0;
      }
      

      https://docs.angularjs.org/api/ngResource/service/$resource

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-01-11
        • 1970-01-01
        • 2019-07-06
        • 2021-08-17
        • 2013-02-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多