0

I don't really understand how to inherit controller objects in angular (not using $scope), when we're surrounding them in a IIFE.

So assume we have 2 controller files:

Animal.js

(function() {
    'use strict';
    angular.module('myApp').controller('animalCtrl', function() {
        this.strength = 3;
        this.speed = 3;
});
})();

Beaver.js

(function() {
    'use strict';
    angular.module('myApp').controller('beaverCtrl', function() {
        //How do I inherit the parent controllers stats?
});
})();

How can I inherit from animalCtrl using my beaverCtrl?

1

2 Answers 2

2

The best way to share data on any angularjs site is by using services. In this case I would create a factory that will store strength and speed and share it with beaverCtrl.

angular.module('<yourappname>', [])
  .factory('dataService', function() {
    $scope = this;

    $scope.strength = null;
    $scope.speed = null;

    $scope.setStrength = function(value) {
      $scope.strength = value;
    }

    $scope.setSpeed = function(value) {
      $scope.speed = value;
    }
    return $scope;
})

Then in the controllers you would call the service like this

.controller('animalCtrl', function(dataService) {
  this.strength = 3;
  this.speed = 3;

  dataService.setStrength(this.strength);
  dataService.setSpeed(this.speed);

});

.controller('beaverCtrl', function(dataService) {
  this.strength = dataService.strength;
  this.speed = dataService.speed;
});
Sign up to request clarification or add additional context in comments.

Comments

2

It's important to realize that an AngularJS controller is just a normal javascript "class". The only catch is invoking the base constructor with dependency injection.

// Create some base class.
BaseController = function($scope, $route) {
  // Do some stuff here.
};

// The base class has some behavior.
BaseController.prototype.someMethod = function() { /* do something */ };

// Create some child class.
ChildController = function($scope, $injector) {
  // Invoke the base constructor.
  $injector.invoke(this, BaseController, {$scope: $scope});
};

// Inherit from the base class.
ChildController.prototype = Object.create(BaseController.prototype);

// Add more specific behavior.
ChildController.prototype.someChildMethod = function() { /* do something */ };

Then you can register your controller as

angular.module('myApp').controller('ChildController', ChildController);

Keep in mind that using inheritance like this will be problematic if overused. It should only be used for sharing behavior. Additionally, using composition of different "classes" is generally going to be much more flexible than using inheritance.

From a code organization standpoint, I would also recommend that you declare your controllers in one place (one file per controller) and register them onto modules in another place (one file per module).

2 Comments

I'm a bit confused how you can call $injector.invoke(this, BaseController, {$scope: $scope}); If the controllers are in different files with an IIFE surrounding them, then the BaseController isn't visible to the ChildController. I guess this is more of a javascript issue than an angular one, but your response was helpful.
I omitted the organization parts to keep the example simple. In a real application, you'd want to have some kind of load-time module system. Angular modules deal with run-time dependencies (i.e., configuring the dependency injector and html compiler).

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.