javascript - Using deeply nested object from JSON in AngularJS - strange behavior -
i'm trying understand how angularjs sees object nested json. here's example plunker. data comes service , assigned $scope.data
. javascript code seems want me declare every level of object first before usage, referencing deep level within object view html works, , using deep level in function kinda works. it's rather inconsistent.
i'm not sure if understanding of $scope
lacking, or if has promise objects. advise please?
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 function works 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 break whole app // $scope.nestedobj = $scope.data.level1.level2; // using nested obj in function works 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" ] } }
your $http
request asynchronous.
app.controller('mainctrl', function($scope, jsonsvc) { jsonsvc.read('data.json', $scope); //$scope.data.level1.level2 doesn't exist yet @ point in time //and throws exception $scope.nestedobj = $scope.data.level1.level2; //$scope.data.level1.level2 doesn't exist yet @ point in time //and throws exception //once angular dirty checking 1 work since //$http request finished. $scope.getlen = function () { return $scope.data.level1.level2.length }; });
since have 3 scope objects rely on data best assign in 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 not want set on call back, use $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; }; }); });
Comments
Post a Comment