Sign up ×
Stack Overflow is a community of 4.7 million programmers, just like you, helping each other. Join them; it only takes a minute:

Within a module, a controller can inherit properties from an outside controller:

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

var ParentCtrl = function ($scope, $location) {
};

app.controller('ChildCtrl', function($scope, $injector) {
  $injector.invoke(ParentCtrl, this, {$scope: $scope});
});

Example via: http://blog.omkarpatil.com/2013/02/controller-inheritance-in-angularjs.html

Can also a controller inside a module inherit from a sibling?

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

app.controller('ParentCtrl ', function($scope) {
  //I'm the sibling, but want to act as parent
});

app.controller('ChildCtrl', function($scope, $injector) {
  $injector.invoke(ParentCtrl, this, {$scope: $scope}); //This does not work
});

The second code does not work since $injector.invoke requires a function as first parameter and does not find the reference to ParentCtrl.

share|improve this question
    
This should help: stackoverflow.com/questions/16828287/… – Bart Aug 27 '13 at 10:14
2  
aside: this doesn't look like inheritance, but more like sharing methods or injecting. Perhaps just semantics. – alockwood05 Jan 23 at 21:01
    
The link for the example isn't valid anymore. – AlexS Jun 17 at 5:15
    
Google Cache Link: webcache.googleusercontent.com/… which points to this interesting Fiddle: jsfiddle.net/mhevery/u6s88/12 – Federico Elles Jun 18 at 18:22

4 Answers 4

up vote 175 down vote accepted

Yes, it can but you have to use the $controller service to instantiate the controller instead:-

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

app.controller('ParentCtrl ', function($scope) {
  // I'm the sibling, but want to act as parent
});

app.controller('ChildCtrl', function($scope, $controller) {
  $controller('ParentCtrl', {$scope: $scope}); //This works
});
share|improve this answer
    
ParentCtrl should be a controller or is it possible to use a service ? – gontard Mar 6 '14 at 13:54
    
@gontard: In this case it must be a controller, as $controller can only use registered controllers. – ZeissS Mar 13 '14 at 10:00
3  
It is a very good solution. Thank you. But how would I do it in case I am using Controller As syntax? – To Ka Oct 24 '14 at 14:24
1  
The above fiddle was asked as a question. It's worth noting that controllerAs simply assigns the controller to the scope - So you would change $scope to this (in theory) – Dan Pantry Mar 2 at 14:15
1  
This worked for me, however I'm trying to do this in a way that I have the parent controller and the child controller on the same page. This causes the $http operation in the parent controller to run twice. When the child controller injects the scope of the parent controller my $scope.AllMembers array get's populated twice as the parent controller causes it to run, then the child controller causes it to run again. Is there any way to prevent that? – Ryios Jul 15 at 20:21

I think,you should use factory or service,to give accessible functions or data for both controllers.

here is similar question ---> AngularJS controller inheritance

share|improve this answer
    
Yes that is one way, thanks. I came across that post when I was searching for solution. I was thinking if there was some way to load controller function and extend "this" with it. – To Ka Oct 25 '14 at 20:31
    
I would like to have a universal loading variable so that when data is loading I always do the same thing, I don't think factories can do that. My parent controller can have a loading variable but the factory can't manipulate it... right?! – PixMach Sep 15 at 0:16

As mentioned in the accepted answer, you can "inherit" a parent controller's modifications to $scope and other services by calling: $controller('ParentCtrl', {$scope: $scope, etc: etc}); in your child controller.

However, this fails if you are accustomed to using the controller 'as' syntax, for example in

<div ng-controller="ChildCtrl as child">{{ child.foo }}</div>

If foo was set in the parent controller (via this.foo = ...), the child controller will not have access to it.

As mentioned in comments you can assign the result of $controller directly to the scope:

var app = angular.module('angularjs-starter', []);
app.controller('ParentCtrl ', function(etc...) {
    this.foo = 'bar';
});
app.controller('ChildCtrl', function($scope, $controller, etc...) {
    var inst = $controller('ParentCtrl', {etc: etc, ...});

    // Perform extensions to inst
    inst.baz = inst.foo + " extended";

    // Attach to the scope
    $scope.child = inst;
});

Note: You then must remove the 'as' part from ng-controller=, because you are specifying the instance name in the code, and no longer the template.

share|improve this answer

Well, I did this in another way. In my case I wanted a function that apply the same functions and properties in other controllers. I liked it, except by parameters. In this way, all yours ChildCtrls need to receive $location.

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

function BaseCtrl ($scope, $location) {
    $scope.myProp = 'Foo';
    $scope.myMethod = function bar(){ /* do magic */ };
}

app.controller('ChildCtrl', function($scope, $location) {
    BaseCtrl.call(this, $scope, $location);

    // it works
    $scope.myMethod();
});
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.