With the original way to define controllers, accessing the parent's scope was fairly trivial, since the child scope prototypically 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 the recommended way to declare a controller. But with Controller-As, the above approach no longer works.
Sure, I can access the parent scope with pc.name
from the View:
<div ng-controller="parentCtrl as pc"> {{pc.name}} <div ng-controller="childCtrl as cc"> {{cc.childName}} </div> </div>
I do have some issues with this (potential for spaghetti code), but this question is about accessing the parent scope from the child controller.
The only way I can see this working 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's no $scope.name // and no $scope.$parent.name });
So now, the child controller needs to know about "pc
" - except, this should (in my mind) be restricted to the view. I don't think a child controller should know about the fact that a view decided to declare a ng-controller="parentCtrl as pc"
.
Q: What's the right approach then?
EDIT:
Clarification: I'm not looking to inherit a parent controller. I am looking to inherit/change the shared scope. So, if I was to amend the first example, I should be able to do the following:
app.controller("parentCtrl", function($scope){ $scope.someObj = {prop: "not set"}; }) .controller("childCtrl", function($scope){ $scope.someObj.prop = "changed"; });
After researching, I came to the following realization:
Controller-As approach is NOT a substitute for using
$scope
. Both have their place, and can/should be used together judiciously.
$scope
does exactly what the name implies: i.e. it defines ViewModel properties on the $scope
. This works best for sharing scope with nested controllers that can use the $scope
to drive their own logic or to change it.Here's 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>
You should do like :
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With