Search code examples
angularjsangularjs-controllerangularjs-factory

AngularJS: Controller inheritance using call (or apply)


This is something I discovered when trying to make my controllers more reusable.

app.factory('BaseController', function(myService) {
  return function(variable) {
    this.variable = variable;
    this.method = function() {
      myService.doSomething(variable);
    };
  };
})

.controller("ChildController1", function($scope, BaseController) {
  BaseController.call($scope, "variable1");
})

.controller("ChildController2", function($scope, BaseController) {
  BaseController.call($scope, "variable2");
});

And now I can do something like this in my HTML (e.g inside ng-controller="ChildController1"): ng-click="method()"

The code simply works. But I don't know how it really works (what kind of pattern is it?) and would it be a good practice to do so?


Solution

  • Your solution works more or less like this:

    app.factory('mixinBaseController', function(myService) {
      return function (scope, variable) {
        angular.extend(scope, {
          variable: variable;
          method: function() {
            myService.doSomething(variable);
          }
        });
      };
    })
    
    .controller("ChildController1", function($scope, mixinBaseController) {
      mixinBaseController($scope, "variable1");
    })
    
    .controller("ChildController2", function($scope, mixinBaseController) {
      mixinBaseController($scope, "variable2");
    });
    

    Can you see? By your .call($scope, ...) is just setting the context (this) to the real $scope and this way the BaseController just extends your scope with properties and functions.

    This is only to demonstrate how your code works.

    To achieve a more JavaScript like inheritance, please see:

    You should as well have a look at the "controllerAs" syntax introduced in AngularJS 1.2. I highly recommend to use controllerAs. This also should help to implement inheritance for your controllers.