繁体   English   中英

无法访问JavaScript对象属性

[英]Cant access JavaScript object property

即使属性存在,我也无法访问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;
  });

控制台中的输出: 在此处输入图片说明

有人也问一下( 这里 ),但他没有解决。 我也尝试了那里提出的建议:使用键,控制台会引发“未定义的函数”错误。 您还可以注意到, $http内的log() // 9的调用晚于其他函数。 这可能是原因吗? 但是请注意log() // 13 已经可以打印对象了。

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

我还尝试了下标: DataFactory["expenses"]结果相同

有人可以告诉我我做错了吗?

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

查看控制台语句的顺序。 第13行(在$http.get() )发生在第9行之前(在$http.get().success处理程序中)。 因此,在第13行,还没有分配fac.expenses的方式。 即使标记为第4,5,6行的行也发生在第9行之后设置fac.expenses之前。

看来您没有编写用于异步网络调用的代码,这就是为什么它不能正常工作的原因。 您只能从.success handler可靠地使用fac.expenses ,也可以从.success handler中调用.success

另外,由于这是与时间相关的问题,因此可以通过调试工具以多种方式欺骗您。 通常,您应该记录要查找的实际值,而不是父对象,因为当您以后尝试在日志中钻取父对象时, console.log()可能会使您感到困惑(因为它已经被填充了) 。


我不太了解您在此处要尝试实现的内容,也不知道确切建议什么,但是如果您要使用fac.expenses ,则必须在最初返回它的.success处理函数中使用它,或者您可以调用其他函数并将fac.expenses传递给该其他函数。 您无法像执行操作那样从异步回调中返回它,并且期望它在可能已经执行过的其他链接代码中可用。

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

暂无
暂无

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

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