How to access parent property using Controller As notation

All we need is an easy explanation of the problem, so here it is.

I’m using the Controller as in my view as follows:

<body ng-controller="MainCtrl as main">
   <div ng-controller="ChildCtrl as child">
      {{ main.parentValue }} + {{ child.childValue }}
   </div>
</body>

Defining my controller like this:

app.controller('MainCtrl', function($scope) {
   this.parentValue = 'Main';
});

app.controller('ChildCtrl', function($scope) {
   this.childValue = 'Child';
   // I want to access the property of the parent controller here
});

How can the ChildCtrl set the name property of the MainCtrl? Here the Plunkr.

Using the $scope notation, I could have accessed $scope.parentValue from the child controller. How can the same functionality be achieved using the Controller As notation?

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

Since your using the “controller as” notation, witin your ChildCtrl you can access the MainCtrl using $scope.main, for example $scope.main.name.

See my snippet below.

var app = angular.module('app', []);

app.controller('MainCtrl', function($scope) {
  this.name = 'Main';
  this.test = {};
});

app.controller('ChildCtrl', function($scope) {
  this.name = 'Child';
  alert($scope.main.name);
});
<html ng-app="app">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<body ng-controller="MainCtrl as main">
  <div ng-controller="ChildCtrl as child">
    {{ main.name }} + {{ child.name }}
  </div>
</body>

</html>

Method 2

You should not mix up “controller as” and $scope usage. To update data in a parent-scope you could/should use services.

Example: Changing the page-title from within any Child-Controller:

app.service("SiteService", function () {
    return {
        title: "Page title";
    }
}


app.controller ("ParentCtrl", function (SiteService) {
    this.site = SiteService;
}

app.controller ("ChildCtrl", function (SiteService) {
    SiteService.title = "New Title";
}

And your template

<html ng-app="someApp" ng-controller="ParentCtrl as site">
    <head>
         <title>{{site.title}}</title>
    </head>
</html>

The main advantage of this approach: You separate public mutable from private properties.

Method 3

Putting the data in $scope is the angular way to do this. You could also set/get your data from a service which is then easy to include into either controller.

Check out this video: https://egghead.io/lessons/angularjs-sharing-data-between-controllers

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply