Undefined Variable Inside Controller ($scope issue

2019-08-09 07:27发布

All, I have the following AngularJS below. Why is $scope.gotData not visible outside of the call to getData.success()? Note that $scope.gotData is visible to the view: I can display the value of scope.gotData by placing {{gotData}} within my index.html.

Why can I not access $scope.gotData as a variable elsewhere in my controller? This is a question concerning the details of $scope.

getData.js

myApp.factory('getData',function($http){
return $http.jsonp('https://foo.com/bar.json')
       .success(function(data){
            return data;
        })
        .error(function(err){
            return err;
        });
});

MainController.js

myApp.controller('MainController', ['$scope','getData', function($scope, getData){
    getData.success(function(data){
        $scope.gotData = data;
    });

    $scope.gotData /* NOT DEFINED HERE */
   }]);

index.html

<html>
  <head>
    <script src="js/vendor/angular.js"></src>
  </head>
  <body ng-app="MyApp">
    <div ng-controller="MainController">
      {{gotData}} /* I CAN SEE THE DATA HERE */
     </div>
  </body>
</html>

3条回答
干净又极端
2楼-- · 2019-08-09 07:57

Although not the best programming practice, but a solution to this is to use $rootScope.

myApp.controller('MainController', ['$scope','getData', function($scope, getData){
    getData.success(function(data){
        $rootScope.gotData = data;
    });

    console.log($rootScope.gotData) // this will be accessible across
                                    // different controllers aswell
   }]);

查看更多
Lonely孤独者°
3楼-- · 2019-08-09 08:05

the call to getData.success is asynchronous. So before executing that success function, your call to console of $scope.gotData is done. So you are supposed to define a default value of this $scope.gotData beforehand. And when you get a success call, only then you should use it. Something like this :

myApp.controller('MainController', ['$scope','getData', function($scope,getData){

    $scope.gotData = null;

    getData.success(function(data){
        $scope.gotData = data;
    });

    if($scope.gotData != null) 
        // Do something useful with this data
}]);
查看更多
Ridiculous、
4楼-- · 2019-08-09 08:23

The reason why you cannot see $scope.gotData outside the getData.success() function is because .success() is async and the value is not available when you try to access it outside .success(). This essentially means that the promise has not been resolved yet.

Moreover, once angular's digest cycle identifies that $scope.gotData is populated, it quickly updates the view. Thats the reason why you can see $scope.gotData in the view

Things would be more clear once you put a watch on $scope.gotData

 myApp.controller('MainController', ['$watch','$scope','getData', function($watch,$scope, getData){
     getData.success(function(data){
        $scope.gotData = data;
     });

    $scope.$watch($scope.gotData,function(n,o){
       console.log("new val-> "+n);
       console.log("old val->"+o);
     })   
 }]);
查看更多
登录 后发表回答