2014-06-21 211 views
0

即使属性存在,我也无法访问JavaScript对象的属性。我正在尝试访问AngularJS中的Factory对象的属性。下面是代码:无法访问JavaScript对象属性

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

并在控制台输出中的: enter image description here

有人还问(here)关于这个,但他并没有得到解决。我也尝试了那里的建议:使用键,控制台会抛出“未定义的函数”错误。你也可以注意到$http里面的日志里面的log() // 9被调用比其他函数晚;这是原因吗?但是请注意log() // 13可以已经打印对象

我认为AngularJS可能有问题,我尝试了一些全局变量d and e,用于测试目的,它们也提供了相同的结果。

我也试过标:DataFactory["expenses"]具有相同的结果

有人可以告诉我什么,我做错了什么?

+0

的console.log不打印继承属性 – Ven

+0

@Ven什么是继承属性? –

+0

如果'd.expenses'有数据,但'e'没有,这意味着d.expenses'(或'DataFactory.expenses')被替换为另一个对象,所以它变得与'e'不同。 – Oriol

回答

2

您正在使用异步调用,但试图将它们视为同步发生。这完全不起作用,因为在网络调用请求结果实际完成并返回之前,最终尝试使用结果。

查看控制台语句的顺序。第13行(在$http.get()之后)发生在第9行之前(在$http.get().success处理程序中)。所以,在第13行,目前还没有办法分配fac.expenses。即使是标有第4,5,6行的行发生在第9行之后fac.expenses之后。

看起来您没有编写代码来使用异步网络调用,这就是为什么它不能正常工作。您只能从.success handler内部可靠地使用fac.expenses,或从.success处理程序中调用某些东西。

此外,由于这是一个与时间有关的问题,您可以通过调试工具以各种方式欺骗您。一般来说,您应该记录您要查找的实际值,而不是父对象,因为console.log()可能会在您稍后尝试钻入日志中的父对象(因为它已被填充)时混淆您。


我不太明白你想在这里实现确切地知道推荐什么,但如果你想使用fac.expenses,那么你必须使用它的.success处理器内的地方最初是返回的,或者您可以调用其他函数并将fac.expenses传递给该函数。你不能像你正在做的那样从异步回调中返回它,并期望它可以在其他可能已经执行的链接代码中使用。

1

jfriend00砸在头上。您从DataFactory服务返回空对象,然后从Ajax服务获取结果。异步调用的本质是,代码继续运行,返回空对象,同时等待服务器的响应。异步会让所有人第一次遇到它,但是接下来你会认识到这种模式。

有一种处理这种称为延期承诺模式的现代方式。 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; 
    }); 
}]);