Search code examples
javascriptangularjsrootscope

Angular root scope and scope issues


I have noticed that in one of my controllers I am getting $rootScope and $scope injected, and they both point to the same object.

Furthermore, in all my other controllers, the $scope object is shared. So whenever I inject scope, it contains the properties/methods assigned to it in all the other controllers that have so far been instantiated.

This isn't an app that I worked on from the beginning and it's pretty massive. I haven't seen this behavior before and I don't know where to begin diagnosing it. Any ideas what is causing this?

The way that we are setting up our controllers/directives is pretty standard and it looks like this:

angular.module('myApp')
  .directive('mainNav', function() {
    return {
      restrict: 'A',
      templateUrl: 'scripts/directives/mainNav/mainNav.html',
      controller: 'mainNavCtrl',
      replace: true,
      link: function(scope, element) {
          //Do DOM-related stuff
        });
      }
    };
  })
  .controller('mainNavCtrl', function($rootScope, $scope, $state) {
    //Do controller stuff
  });

We do also configure our app as follows:

angular.module('myApp', ['ui.router', 'kendo.directives'])
.config(function ($stateProvider, $urlRouterProvider) { $urlRouterProvider.otherwise('/');

$stateProvider
  .state('app', {
    url: '/',
    templateUrl: 'views/app.html',
    resolve: {
      //Fetch stuff
    }
  })
  ;   });

In response to Kursad Gulseven's comment, this is what I'm seeing in Batarang:

Batarang screenshot

The scope with ID 002 gets passed in as $scope and $rootScope to the first controller. When properties are added to $scope, they show up on $rootScope. Then all the other controllers are receiving the scope with ID 00A. So properties added to $scope in those controllers are visible to all other controllers getting $scope injected.


Solution

  • $rootScope and $scope are not the same object.

    If you have an object named anObject in root scope and it has an attribute named anAttribute; then you can access that attribute using $scope like this:

    $scope.anObject.anAttribute
    

    That's because Angular looks up parent scopes if it cannot find an object in $scope.

    UPDATE:

    Your mainNav directive should have an inherited child scope by adding scope: true. When "scope" is false, which is the default setting for directives, the parent controller and directive's controller share the same scope object. Setting scope true will create a new child scope for the directive.