简体   繁体   English

在AngularJS中加载异步数据

[英]Loading asynchronous data in AngularJS

I'm getting a Cannot read property of undefined error when calling a function, however the data is being displayed correctly. 我在调用函数时遇到Cannot read property of undefined错误的Cannot read property of undefined ,但数据正在正确显示。

According to what I've read so far, that's because of asynchronous load of data made by AngularJS and that I should use promises to avoid that. 根据我到目前为止所读到的,这是因为AngularJS对数据的异步加载,我应该使用promises来避免这种情况。

I've searched online and Angular's documentation but I didn't understand how to use it. 我在网上搜索了Angular的文档,但我不明白如何使用它。

I'd appreciate if someone could help me. 如果有人可以帮助我,我会很感激。

Currently, I have the following code: 目前,我有以下代码:

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

}])

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

You should not use $scope.myData.min until $scope.myData is populated, which as you correctly said is asynchronous so can take a moment. 你不应该使用$scope.myData.min直到$scope.myData填充,正如你所说正确的是异步这样可以花点时间。 The simplest solution is in this case just wrap your code into if-block: 在这种情况下,最简单的解决方案是将代码包装到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 is going to be checked in every digest cycle so once $scope.myData is available it the function will evaluate and return diff properly. myFunction将在每个摘要周期中进行检查,因此一旦$ scope.myData可用,该函数将评估并正确返回diff

However , much better approach would be to work with a promise object returned by resource. 但是 ,更好的方法是使用资源返回的promise对象。 In this case you could do something like this: 在这种情况下,您可以执行以下操作:

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

and in HTML use myData without a function: 并在HTML中使用没有函数的myData

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

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

Just define $scope.myData = {} 只需定义$scope.myData = {}

eg for your code: 例如,对于你的代码:

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

}])

Your code is fine, maybe a little modification to avoid 你的代码很好,可能需要稍加修改才能避免

Cannot read property of undefined error 无法读取未定义错误的属性

$scope.myData = Test.get();

Then u can have 那你可以拥有

$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 https://docs.angularjs.org/api/ngResource/service/ $ resource

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM