javascript 在 AngularJS 中使用来自 JSON 的深度嵌套对象 - 奇怪的行为
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16377529/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using deeply nested object from JSON in AngularJS - strange behavior
提问by Ray Shan
I'm trying to understand how AngularJS sees an object from a deeply nested JSON. Here's an example plunker. The data comes from service and is assigned to $scope.data
. The javascript code seems to want me to declare every level of the object first before usage, but referencing a deep level within object from the view HTML always works, and using the deep level in a function kinda works. It's rather inconsistent.
我试图了解 AngularJS 如何从深度嵌套的 JSON 中查看对象。这是一个示例 plunker。数据来自服务并分配给$scope.data
。javascript 代码似乎希望我在使用之前首先声明对象的每个级别,但是从 HTML 视图中引用对象中的深层总是有效的,并且在函数中使用深层还可以。比较矛盾。
I'm not sure if my understanding of $scope
is lacking, or if this has something to do with promise objects. Advise please?
我不确定我的理解$scope
是否缺乏,或者这是否与 promise 对象有关。请指教?
HTML
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
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
JSON
{
"level1": {
"level2": [
"a",
"b",
"c"
]
}
}
回答by Mark Coleman
Your $http
request is asynchronous.
您的$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
};
});
Since you have three scope objects that rely on that data it would be best to assign those in the call back.
由于您有三个依赖于该数据的范围对象,因此最好在回调中分配这些对象。
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;
};
});
}};
});
If you do not want to set it all up on the call back, you could also use $broadcast()
and $on()
如果您不想在回叫时全部设置,您还可以使用$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;
};
});
});
回答by bosco2010
Ray, another option is to return the $http.get call since its a promise and use the .then() function to declare $scope.nestedObj or anything else you want to do with data once it returns.
雷,另一个选择是返回 $http.get 调用,因为它是一个承诺,并使用 .then() 函数声明 $scope.nestedObj 或其他任何你想在数据返回后对数据做的事情。
Here's my example: http://plnkr.co/edit/GbTfJ9
这是我的例子:http: //plnkr.co/edit/GbTfJ9
You can read more about promises in Angular here: http://docs.angularjs.org/api/ng.$q
您可以在此处阅读有关 Angular 承诺的更多信息:http: //docs.angularjs.org/api/ng.$q