0

I'm trying to extend controllers using conrollerAs syntax. My parent and child controllers are not defined in the same scope, so I put the parent controller (BaseController) in a service:

angular.module('myApp').factory('BaseController', function() {
  var BaseController = function(fooService, barService) {
    // base controller constructor logic
  }

  BaseController.prototype = {
    // base controller methods
  }

  return BaseController;
});

Then use it like so:

var ChildController = function(BaseController, fooService, barService) {
  BaseController.apply(this, [fooService, barService]);
}

var BaseController = angular.injector(['myApp']).get('BaseController');

ChildController.prototype = Object.create(angular.extend(BaseController.prototype, {
  fooMethod: function() {
    // do stuff
  }
}));

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

I use ChildController in a ui router state. The state template doesn't load, and I get an error in the console:

Resource for page controller is not defined <div class="ng-scope" ui-view="foo-view">

Any ideas?

1 Answer 1

0

angular.injector creates a new injector instance (which is application instance, if it sounds better) and shouldn't be used in production within Angular app. I.e.

angular.injector(['myApp']).get('BaseController') !== angular.injector(['myApp']).get('BaseController');

You need to put your hands on BaseController dependency when you're still able to register controllers, and the only place for doing this is config phase,

angular.module('myApp').config(function($controllerProvider, BaseController) {
  ...
  $controllerProvider.register('ChildController', ...)
});

This requires BaseController to be constant, not factory, and possibly limits the things you would like to do with it. Sounds less funny, doesn't it?

So a better thing to do here is just

var ChildController = function(BaseController, fooService, barService) {
  angular.extend(this, BaseController.prototype, { ... });
  BaseController.apply(this, [fooService, barService]);
}

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

Angular DI isn't suited well for OOP JS for the reasons shown above and still needs to be supplemented with other modular solutions.

Sign up to request clarification or add additional context in comments.

Comments

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.