我有一个角度控制器,它使用工厂从JSON文件返回响应。 当我尝试遍历返回的数据时,我在注释中看到以下错误。 但是,如果我在角括号内使用HTML中的realArticleData对象,它会完美地横向移动。我认为这与工厂退回的承诺有关,但我不确定。
Controller Snippet:
function SpecialOrderItemsCtrl($scope, $location, articleDataService) {
$scope.realArticleData = articleDataService.getArticles();
//This throws TypeError: Cannot read property 'thdCustomer' of undefined
$scope.custInfo = $scope.realArticleData.articles.thdCustomer;
}
HTML代码段:
<div ng-controller=SpecialOrderItemsCtrl>
<label>Raw Article JSON</label>
<p>{{realArticleData}}</p>
<label>Json transversed by one level</label>
<p>{{realArticleData.articles}}</p>
<label>THD CUstomer </label>
<p>{{realArticleData.articles.thdCustomer}}</p>
</div>
厂:
function articleDataService($rootScope, $http) {
articleDataService.data = {};
articleDataService.getArticles = function() {
$http.get('articleData.json')
.success(function(data) {
articleDataService.data.articles = data;
});
return articleDataService.data;
};
return articleDataService;
}
sendDesign.factory('articleDataService', articleDataService);
答案 0 :(得分:4)
你正在处理承诺。因此,您需要异步处理它们。 如在
angular.module('plunker', []).controller('SpecialOrderItemsCtrl', ['$scope', 'articleDataService', function($scope, articleDataService){
// when promise is resolved, set the scope variable
articleDataService.getArticles().then(function(articles){
// store any data from json that you want on the scope for later access in your templates
$scope.articles = articles;
})
}]).factory('articleDataService',['$http', '$q', function($http, $q){
var data = null;
return {
getArticles: function() {
var promise;
if(data === null) {
promise = $http.get('articleData.json').then(function(response){
// cache the response
data = response;
return response;
});
} else {
var deferred = $q.defer();
// promise is immediately resolved with the cached data
// this way both cached and async data can be handled consistently
promise = deferred.promise;
}
return promise;
}
} ;
}]);
Plunkr链接:http://plnkr.co/edit/7Oas2T
答案 1 :(得分:2)
将您的服务更改为:
articleDataService.getArticles = function() {
$http.get('articleData.json').then(function(result) {
return result.data
});
}
在你的控制器中:
articleDataService.getArticles().then(function(data) {
$scope.realArticleData = data;
$scope.custInfo = $scope.realArticleData.articles.thdCustomer;
});
你需要按照承诺模式回到控制器,否则你不会等待你的电话完成,你将收到undefined
答案 2 :(得分:2)
要记住的关键点是,承诺不返回值,当值或值到达时,它们使用值执行某些操作。
这个答案是基于@VladimirGurovich和@tymeJV的答案。
这是一个简单的工厂:
var app = angular.module('myApp', []);
app.factory('Names', ['$http', function($http) {
return {
url: 'names.json',
fetch: function() {
return $http.get(this.url, {cache: true}).then(function(json) {
return json.data;
});
}
};
}]);
Names
工厂本身返回一个对象。 fetch
方法从$http.get
返回承诺链。这使用.then()
而不是.success()
,因此结果可以链接。工厂可以直接返回$http
承诺,但给我的操作命名似乎更清晰。
@ VladimirGurovich的回答是手动处理缓存,但Angular可以为我们做这件事,只需将{config: true}
等配置对象和$http.get
一起发送到网址。
这是一个简单的小控制器,它依赖于来自Names
工厂的数据:
app.controller('MainCtrl', ["$scope", "Names", function($scope, Names) {
Names.fetch().then(function(data) {
$scope.names = data.names;
});
}]);
当Names.fetch()
承诺完成时,$scope.names
将填充返回的数据。
这是一个基于此的Plunker:http://plnkr.co/edit/nMx1XL