0

I have the below structure of html/angular:

<div controller="one-controller">
   <div controller="two-controller">
      <div controller="three-controller">
         <div controller="four-controller">

         </div>
      </div>
   </div>
</div>

I want to access the scope of "one-controller" from "four-controller", how do I do that.

I have read that typically all child controllers have by default access to parents controller, but in my case its not working. As read, I see that for one level up, $scope.$parent... will work, but in my case, how do I access the top level one.

Do I need to use $rootScope for that or is there any other way.

whyAto8
  • 1,660
  • 4
  • 30
  • 56
  • Child scopes should be able to access parent scope. Check carefull the scope hierarchy using chrome tool like `batarang`. Maybe some directive is creating an insolated scope. – Chandermani Jan 19 '15 at 09:11
  • Yeah, i understand, something like isolated scope could be an issue. I will check that. – whyAto8 Jan 19 '15 at 10:48

4 Answers4

3

The proper way to send messages between nested controllers is using $scope.broadcast and $scope.emit. Specifically, $broadcast travels downwards in the parent-child scope relationship, and $emit travels upwards.

Therefore, if you wanted to communicate with one-controller from within four-controller:

function one-controller($scope) {
  $scope.$on('myEvent', function(event, data) { console.log(data); });
  //Output will be ["apple","orange","banana"]
}

function four-controller($scope) {
  $scope.$emit('myEvent', ["apple","orange","banana"]);
}

And using $broadcast if you wanted to communicate downwards instead:

function four-controller($scope) {
  $scope.$on('myEvent', function(event, data) { console.log(data); });
  //Output will be ["apple","orange","banana"]
}

function one-controller($scope) {
  $scope.$broadcast('myEvent', ["apple","orange","banana"]);
}
Pangolin
  • 161
  • 3
  • I am not sure if this is apt solution for me, I just want to access a property which is stored in top level controller scope. – whyAto8 Jan 19 '15 at 10:49
  • Thanks Pangolin this was an awesome way to handle the problem elegantly! – IfTrue Sep 16 '15 at 14:24
1

You could certainly do this:

function topScope() {
    var scope = $scope;
    while (scope && scope.$parent !== $scope.$root) {
        scope = scope.$parent;
    }
    return scope;
}

Example: http://jsfiddle.net/aakwmhu8/1/

This would save you from having to know exactly how many levels to go up, but as others have said, there are probably better ways to accomplish what you are trying to do. I would say that explicitly accessing the scope of other controllers should be done as little as possible.

JLRishe
  • 99,490
  • 19
  • 131
  • 169
0

It would be best to design your AngularJS application such that you do not require cross-scope access. The complexity raises and maintainability suffers if you create a scope-spaghetti.

But if you reall want to do so: As you allready said you can do

$scope.$parent.$parent.$parent 

and you should have the scope of your to level controller. You could also use the $rootScope like this in your top level controller:

$rootScope.myTopLevelControllerScope = $scope;

Now you can access this scope from every controller via

$rootScope.myTopLevelControllerScope

But as said in the beginning this is not a nice architecture. Think about whether you can achieve what you want in a nicer way maybe using services or dependency injection which is a strong feature of AngularJS. You may also refer to this question that has some nice references explaining services, factories and providers in AngularJS.

Community
  • 1
  • 1
Sjoerd222888
  • 3,228
  • 3
  • 31
  • 64
0

Child controllers have by default access to parents controller but you can't change primitive type in the parent controller from the child controler so if you want to change something in the parent make sure you save your data in object and not in string for example

this will not work

app.controller('parent', function ($scope) {
  $scope.foo = "test";
});

app.controller('child', function ($scope) {
  $scope.foo = "change"; //will not change the parent value
});

this will work

app.controller('parent', function ($scope) {
  $scope.data = {}
  $scope.data.foo = "test";
});

app.controller('child', function ($scope) {
  $scope.data.foo = "change"; //will change the parent value
});
Ariel Henryson
  • 1,316
  • 1
  • 10
  • 13
  • Well, I am not able to access the top level parent somehow and I am not changing the value. I am just trying to access the value which is stored in the property in top level controller – whyAto8 Jan 19 '15 at 10:48
  • I can't help you without see your code. can you put your code or a demo of your code in Plunker so i can review it ? – Ariel Henryson Jan 19 '15 at 11:25