即使属性存在,我也无法访问JavaScript对象的属性。我试图访问AngularJS中的Factory对象的属性。以下是代码:
angular.module("appManager")
// factories.js
.factory("DataFactory", function ($http) {
var fac = {};
fac.expenses = {};
$http.get("mvc/m/revenue.json")
.success(function (result) {
console.log(result); // line 9
fac.expenses = result.expenses;
});
console.log(fac); // line 13
return fac;
})
// expenseController.js
.controller("expenseCtrl", function($scope, DataFactory){
$scope.data = DataFactory.expenses;
console.log(DataFactory); // line 4
console.log(DataFactory.expenses); // line 5
console.log($scope.data); // line 6
// Global // var d = {};
d = DataFactory;
e = DataFactory.expenses;
});
控制台中的输出:
有人也问过(here)这个,但他没有得到解决方案。我也尝试了那里的建议:使用键,控制台抛出“未定义的函数”错误。您还可以注意到log() // 9
内的日志$http
比其他函数更晚调用;这可能是原因吗?但请注意log() // 13
可以已经打印对象。
我认为AngularJS可能有问题,我尝试了一些全局变量d and e
,用于测试目的,这也提供了相同的结果。
我也尝试了下标:DataFactory["expenses"]
,结果相同
有人可以告诉我我做错了吗?
答案 0 :(得分:2)
您正在使用异步调用,但尝试将它们视为同步发生。当您最终尝试在网络调用之前尝试使用结果时,这根本不起作用,该网络调用请求结果实际已完成并已返回。
查看控制台语句的顺序。第13行($http.get()
)调用发生在第9行之前(在.success
的{{1}}处理程序中)。因此,在第13行,我们无法分配$http.get()
。甚至标记为第4,5,6行的那些也发生在第9行之后fac.expenses
之前。
您似乎没有编写代码来处理异步网络呼叫,这就是它无法正常工作的原因。您只能在fac.expenses
内或fac.expenses
处理程序中调用的内容中可靠地使用.success handler
。
此外,由于这是与时间相关的问题,因此您可以通过调试工具以多种方式欺骗。通常,您应该记录您要查找的实际值,而不是父对象,因为.success
在您稍后尝试钻入日志中的父对象时可能会让您感到困惑(因为它已被填充)在)。
我并不完全按照您在此处尝试实现的目标来确切知道要推荐什么,但如果您想使用console.log()
,那么您必须在最初返回它的fac.expenses
处理程序,或者您可以调用其他函数并将.success
传递给其他函数。您无法像您正在做的那样从异步回调中返回它,并希望它可以在已经执行过的其他链式代码中使用。
答案 1 :(得分:1)
有一种现代的方法来处理这种称为延迟承诺的模式。 Angular中的$ q服务为您提供延迟对象。
https://docs.angularjs.org/api/ng/service/ $ Q
所以你使用$ q的服务看起来像这样:
.factory("dataFactory", ['$http', '$q', function ($http, $q) {
var fac = $q.defer();
$http.get("mvc/m/revenue.json")
.success(function (result) {
fac.resolve(result);
});
return fac.promise;
}]);
然后您的控制器看起来像
.controller("expenseCtrl", ['$scope', 'dataFactory', function($scope, dataFactory){
dataFatory.then(function(data) {
$scope.data = data.expenses;
});
}]);