我试图了解AngularJS如何从深层嵌套的JSON中看到一个对象。 Here's an example plunker。数据来自服务并分配给$scope.data
。 javascript代码似乎希望我在使用之前首先声明对象的每个级别,但是从视图HTML中引用对象内的深层始终有效,并且在函数中使用深层有用。这是相当不一致的。
我不确定我对$scope
的理解是否缺乏,或者这是否与promise对象有关。建议好吗?
HTML
<body ng-controller="MainCtrl">
Referencing nested obj in view works:
{{data.level1.level2}}
<br>
Using nested obj within declared scope var doesn't work:
{{nestedObj}}
<br>
Using nested obj in a function works but throws TypeError:
{{getLen()}}
</body>
的Javascript
var app = angular.module('app', []);
app.factory('JsonSvc', function ($http) {
return {read: function(jsonURL, scope) {
$http.get(jsonURL).success(function (data, status) {
scope.data = data;
});
}};
});
app.controller('MainCtrl', function($scope, JsonSvc) {
JsonSvc.read('data.json', $scope);
// Using nested obj within declared scope var doesn't work
// Uncomment below to break whole app
// $scope.nestedObj = $scope.data.level1.level2;
// Using nested obj in a function works but throws TypeError
// Declaring $scope.data.level1.level2 = [] first helps here
$scope.getLen = function () {return $scope.data.level1.level2.length};
});
JSON
{
"level1": {
"level2": [
"a",
"b",
"c"
]
}
}
答案 0 :(得分:3)
您的$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;
};
});
}};
});
如果您不希望在回叫中全部设置,还可以使用$broadcast()
和$on()
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;
};
});
});
答案 1 :(得分:3)
Ray,另一种选择是返回$ http.get调用,因为它是一个promise,并使用.then()函数声明$ scope.nestedObj或者一旦返回就要对数据做任何其他事情。
以下是我的示例:http://plnkr.co/edit/GbTfJ9
您可以在此处详细了解Angular中的承诺:http://docs.angularjs.org/api/ng.$q