3

When I extend a controller in angular, is there any way to call a function on the "superclass" controller from a "subclass" function that overrides it?

For clarity - in Java I'd do:

class Foo {
    void doStuff(){
        //do stuff 
    }
} 

class FooBar extends Foo {
     void doStuff(){
         super.doStuff();
         //do more stuff
     }
}

and I'd like to do the equivalent in angular - something

myApp.controller('FooCtrl', function($scope){

    $scope.doStuff = function(){
         //do stuff
     }
}).controller('FooBarCtrl', function($scope){
   angular.extend(this, $controller('FooCtrl', {$scope: $scope}));

   $scope.doStuff = function(){
          // ??? <- INSERT ANSWER HERE  
         //do more stuff
     }
}
2
  • 1
    Short answer: yes (see: stackoverflow.com/a/19670187/624590 ). Long answer (/opinion): consider mixins or factories as your means of DRYing your code instead of extends/inheritance. Commented May 15, 2015 at 1:52
  • But to make your attempt work, stash the old function somewhere before overriding it: var superDoStuff = $scope.doStuff; $scope.doStuff = function(){ superDoStuff(); /* do more stuff */ }; Commented May 15, 2015 at 2:04

2 Answers 2

1

I wouldn't recommend this pattern, but as an answer to the question, here is a way to do it:

myApp.controller('FooCtrl', function($scope){

    $scope.doStuff = function(){
         //do stuff
     }
}).controller('FooBarCtrl', function($scope){
   angular.extend(this, $controller('FooCtrl', {$scope: $scope}));
   //extend the scope
   var super = angular.extend({}, $scope);
   $scope.doStuff = function(){
          // ??? <- INSERT ANSWER HERE  
         //do more stuff
         //call the "superclass" methods
         if(super.doStuff){
            super.doStuff();
         }
   }
}

Spitballing, I suppose of you could write a helper service that allowed you to override properties with references to the superclass implementations to make it cleaner. Perhaps by overriding "this". Something like:

$scope.doStuff = $override($scope.doStuff, function() {

    this();  //calls the original doStuff function
});

.factory('$override', function(){

    return function(method, func){
        return function(){
            return func.apply(method, arguments);
        };
    };
});
Sign up to request clarification or add additional context in comments.

Comments

0

You can use $parent

so

$scope.$parent.doStuff()

2 Comments

Different kind of inheritance. The question is trying to create a controller that has all of the properties of another controller, but can override them with its own (superclass / subclass style), not a controller that's nested in another (as your answer suggests). en.wikipedia.org/wiki/…
@DRobinson - precisely.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.