A problem that may occur when one develops a web application based on AngularJS (1.X) is the fact that you cannot really abstract some common controller or service behavior. Besides, you often have to deal with the problem of controller granularity: do I have to create several sub-controllers ( but in this way, you have to cope with some scope inheritance issues) or do I have to define only one main controller ( but getting an awful big piece of code included in the controller function ).
Angular Inheritance is a library which proposes a third alternative by giving you the possibility to define your controllers and services in an inheritance way. It allows to take advantage of both worlds by introducing inheritance and multi-inheritance-like process in your Angular code.
To install Angular Inheritance, you just need to get the JS files in the dist
folder. A bower version is coming soon. Then, put them in your lib
folder and add in your index file:
<script type="text/javascript" src="<LIB_PATH>/angular-inheritance.js"> </script>
Using Angular Inheritance means thinking Angular controller and service in a JS prototypal way as the following sections suggest.
Angular Inheritance comes with base controller and service from which children inherits. Both controller and service comes with a the $log service as log
attribute. The controller has its scope
as attribute in more.
function BaseController( $scope ) { /* Some code */}
function BaseService( ) { /* Some code */}
Simple inheritance relationship is quite simple to express. First, we define our controller function. For instance:
function ChildController( $scope ) {
this.someAttribute = 'Some value';
this.someMethod = function() { return 'Some method' };
}
Then, just declare the inheritance relation such as:
angular.inherit( "ChildController" , ChildController ).from('BaseController');
Then, if you need to override some methods in a prototypal way, just do it:
ChildController.prototype.someParentMethod = function() { return "some overriden value"; };
Service inheritance proceeds in the way with:
angular.inherit( "ChildService" , ChildController ).from('BaseService');
If you need your controller to inherit from others controllers, you just have to use the method expand
and provide the array of parent controllers:
angular.expand( "ChildController" , ChildControllerFn ).from( [ 'Parent1Controller' , 'Parent2Controller' , 'Parent3Controller' ]);
And for service multi-inheritance:
angular.expand( "ChildService" , ChildController ).from( [ 'Parent1Service' , 'Parent2Service' , 'Parent3Service' ]);
To be in a real inheritance perspective, we need to be able to call parent controller constructor i.e. the controller function. To do this, you do like this:
function ChildController( $scope ) {
this.super('ParentController' /* Identifier of controller */ , [ $scope ] /* List of constructor arguments */ );
}
In this way, you get a super-power: the one to instantiate "manually" the parent controller. That gives you the possibility to define abstract controller and service.
In order to have a clean way to override a controller / service method, you can use the parent method as followas:
ChildController.prototype.someParentMethod = function() {
var parentValue = this.parent( 'ParentController' ).someParentMethod.apply( this , [] );
return "some overriden value of " + parentValue;
};
Some exceptions may arise if you declare randomly your JS files in your index HTML file. The rule is to declare controllers and services based on their inheritance level. A parent controller must be declared before its children.
<script type="text/javascript" src="<SRC_PATH>/parentController.js"> </script>
<script type="text/javascript" src="<SRC_PATH>/childController.js"> </script>
<script type="text/javascript" src="<SRC_PATH>/grandChildController.js"> </script>
You can find examples of how Angular Inheritance works in the example
folder. Particularly, we propose an abstract CRUDS model of controller and service upon which child controller can base. When your Web Application has to complete CRUDS operations on N types of object, the CRUDS example can inspire you to save time and code lines.
0.0.1 Initial stable version