Access a legacy area using the Controller As approach

With the original way of defining controllers, access to the parent area was pretty trivial, since the content area of ​​the prototype inherits from its parent.

app.controller("parentCtrl", function($scope){ $scope.name = "Parent"; }) .controller("childCtrl", function($scope){ $scope.childName = "child of " + $scope.name; }); <div ng-controller="parentCtrl"> {{name}} <div ng-controller="childCtrl"> {{childName}} </div> </div> 

The Controller-As approach seems to be recommended to declare the controller. But with Controller-As, the above approach no longer works.

Of course, I can access the parent scope using pc.name from the view:

 <div ng-controller="parentCtrl as pc"> {{pc.name}} <div ng-controller="childCtrl as cc"> {{cc.childName}} </div> </div> 

I have some problems with this (potential for spaghetti code), but this question is about accessing the parent area from the child controller.

The only way I see this is:

 app.controller("parentCtrl", function(){ this.name = "parent"; }) .controller("childCtrl", function($scope){ $scope.pc.name = "child of " + $scope.name; // or $scope.$parent.pc.name = "child of " + $scope.name; // there no $scope.name // and no $scope.$parent.name }); 

So, now the child controller should know about " pc " - except that this should (in my opinion) be limited to the view. I do not think that the child controller should be aware that the view has decided to declare ng-controller="parentCtrl as pc" .

Q: What is the right approach?

EDIT:

Clarification: I do not want to inherit the parent controller. I am looking to inherit / modify a common area. Therefore, if I corrected the first example, I would have to do the following:

 app.controller("parentCtrl", function($scope){ $scope.someObj = {prop: "not set"}; }) .controller("childCtrl", function($scope){ $scope.someObj.prop = "changed"; }); 
+42
angularjs angularjs-scope angularjs-controller
Oct 30 '14 at 7:39
source share
3 answers

After research, I came to the following understanding:

The Controller-As approach does NOT replace the use of $scope . Both have their place and can / should be used together wisely.

  • $scope does exactly what the name implies, i.e. defines ViewModel properties on $scope . This is best suited for sharing a scope with nested controllers that can use $scope to control their own logic or to change it.
  • Controler-As defines the entire controller object as a ViewModel with a named scope (via the controller alias). This works best only in the view (but not in other controllers) if the View decides whether it wants to reference a specific ViewModel controller.

Here is an example:

 var app = angular.module('myApp', []); // Then the controllers could choose whether they want to modify the inherited scope or not: app.controller("ParentCtrl", function($scope) { this.prop1 = { v: "prop1 from ParentCtrl" }; $scope.prop1 = { v: "defined on the scope by ParentCtrl" }; }) .controller("Child1Ctrl", function($scope) {}) .controller("Child2Ctrl", function($scope) { // here, I don't know about the "pc" alias this.myProp = $scope.prop1.v + ", and changed by Child2Ctrl"; }); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.min.js"></script> <body ng-app="myApp"> <div ng-controller="ParentCtrl as pc"> <div ng-controller="Child1Ctrl"> <div>I know about the "pc" alias: {{pc.prop1.v}}</div> </div> <div ng-controller="Child2Ctrl as ch2"> <div>I only care about my own ViewModel: {{ch2.myProp}}</div> </div> </div> 
+60
Nov 03 '14 at 5:17
source share

You should do the following:

HTML

 <div ng-controller="ChildController as child"> <button type="button" ng-click="child.sayMe()">Say me!</button> </div> 

Js

 var app = angular.module('myApp', []) app.controller('BaseController',function() { this.me = 'Base'; this.sayMe= function() { alert(this.me); } }); app.controller('ChildController', function($scope, $controller) { var controller = $controller('BaseController as base', {$scope: $scope}); angular.extend(this, controller); this.me = 'Child'; }); 

take a look at https://docs.angularjs.org/guide/controller

+7
Oct 30 '14 at 7:57
source share

For those who just want to access the parent scope programmatically, use the $scope service, find the parent scope and access the name used for the controllerAs parent scope, for example:

$scope.$parent.someName.doSomething();

+1
Aug 14 '16 at 4:09
source share



All Articles