Javascript 在AngularJS中使用JSON中的深度嵌套对象-奇怪的行为

Javascript 在AngularJS中使用JSON中的深度嵌套对象-奇怪的行为,javascript,json,angularjs,promise,angularjs-scope,Javascript,Json,Angularjs,Promise,Angularjs Scope,我试图理解AngularJS是如何从深度嵌套的JSON中看到对象的。数据来自服务,并分配给$scope.data。javascript代码似乎希望我在使用之前首先声明对象的每个级别,但是从HTML视图中引用对象中的深层次总是可行的,在函数中使用深层次也是可行的。这很不一致 我不确定我是否缺乏对$scope的理解,或者这是否与promise对象有关。请告诉我好吗 HTML JSON 您的$http请求是异步的 app.controller('MainCtrl', function($scope,

我试图理解AngularJS是如何从深度嵌套的JSON中看到对象的。数据来自服务,并分配给
$scope.data
。javascript代码似乎希望我在使用之前首先声明对象的每个级别,但是从HTML视图中引用对象中的深层次总是可行的,在函数中使用深层次也是可行的。这很不一致

我不确定我是否缺乏对
$scope
的理解,或者这是否与promise对象有关。请告诉我好吗

HTML

JSON


您的
$http
请求是异步的

app.controller('MainCtrl', function($scope, JsonSvc) {
    JsonSvc.read('data.json', $scope);

    //$scope.data.level1.level2 doesn't exist yet at this point in time 
    //and throws an exception
    $scope.nestedObj = $scope.data.level1.level2;

    //$scope.data.level1.level2 doesn't exist yet at this point in time 
    //and throws an exception
    //once Angular does dirty checking this one will work since the 
    //$http request finished.
    $scope.getLen = function () {
        return $scope.data.level1.level2.length
    };
});
由于有三个作用域对象依赖于该数据,因此最好在回调中分配这些对象

app.factory('JsonSvc', function ($http) {
  return {read: function(jsonURL, scope) {
        $http.get(jsonURL).success(function (data, status) {
            scope.data = data;
      scope.nestedObj = scope.data.level1.level2;
      scope.getLen = function () {
        return scope.data.level1.level2.length;
      };
        });
    }};
});
如果您不想在回拨时设置所有设置,还可以使用和


Ray,另一个选项是返回$http.get调用,因为它是一个承诺,并在返回后使用.then()函数声明$scope.nestedObj或您想要对数据执行的任何其他操作

下面是我的例子:


您可以在此处阅读更多关于承诺的信息:

谢谢Mark。我知道
$http
请求是如何未完成的。但一旦JSON对象完成,我如何将其映射到
$scope.data
?我原以为
.success
能解决这个问题,但显然不行。如果JSON很大,有很多级别,那么每个级别是否都需要手动单独映射?
{
    "level1": {
        "level2": [
            "a",
            "b",
            "c"
        ]
    }
}
app.controller('MainCtrl', function($scope, JsonSvc) {
    JsonSvc.read('data.json', $scope);

    //$scope.data.level1.level2 doesn't exist yet at this point in time 
    //and throws an exception
    $scope.nestedObj = $scope.data.level1.level2;

    //$scope.data.level1.level2 doesn't exist yet at this point in time 
    //and throws an exception
    //once Angular does dirty checking this one will work since the 
    //$http request finished.
    $scope.getLen = function () {
        return $scope.data.level1.level2.length
    };
});
app.factory('JsonSvc', function ($http) {
  return {read: function(jsonURL, scope) {
        $http.get(jsonURL).success(function (data, status) {
            scope.data = data;
      scope.nestedObj = scope.data.level1.level2;
      scope.getLen = function () {
        return scope.data.level1.level2.length;
      };
        });
    }};
});
app.factory('JsonSvc', function ($http, $rootScope) {
    return {
        read: function (jsonURL, scope) {
            $http.get(jsonURL).success(function (data, status) {
                scope.data = data;
                $rootScope.$broadcast("jsonDone");
            });
        }
    };
});

app.controller('MainCtrl', function ($scope, JsonSvc) {
    JsonSvc.read('data.json', $scope);
    $scope.name = "world";
    $scope.$on("jsonDone", function () {
        $scope.nestedObj = $scope.data.level1.level2;
        $scope.getLen = function () {
            return $scope.data.level1.level2.length;
        };
    });
});