Skip to content

Instantly share code, notes, and snippets.

@BrainCrumbz
Last active May 12, 2017 03:57
Show Gist options
  • Save BrainCrumbz/5832057 to your computer and use it in GitHub Desktop.
Save BrainCrumbz/5832057 to your computer and use it in GitHub Desktop.
Reusing an AngularJS Directive core code. Please see 'Directives Inheritance' file for an extended description. (Text here comes out unformatted). For a working sample, please see plunkr at http://plnkr.co/edit/6kzpuSGPFfXe6eSH5bc2
angular.module('com.namespace.directives').directive('baseDir', ['$compile', 'baseDirNamespace', baseDirFactory]);
function baseDirFactory($compile, baseDirNamespace) {
return new baseDirNamespace.BaseDirCore($compile);
}
angular.module('com.namespace.directives').factory('baseDirNamespace', baseDirNamespace);
function baseDirNamespace() {
function BaseDirCore($compile) {
// Class constructor function
//...
}
$.extend(true, BaseDirCore.prototype, {
// Shared members
//...
});
return {
BaseDirCore: BaseDirCore
};
}
angular.module('com.namespace.directives').directive('derivedDir', ['$compile', 'derivedDirNamespace', derivedDirFactory]);
function derivedDirFactory($compile, derivedDirNamespace) {
return new derivedDirNamespace.DerivedDirCore($compile);
}
angular.module('com.namespace.directives').factory('derivedDirNamespace', ['baseDirNamespace', derivedDirNamespace]);
function derivedDirNamespace(baseDirNamespace) {
var BaseDirCore = baseDirNamespace.BaseDirCore; // alias
function DerivedDirCore($compile) {
// Class constructor function
//...
}
// setup inheritance chain, with one of the many helpers found on the web
DerivedDirCore.inheritsFrom(BaseDirCore);
$.extend(true, DerivedDirCore.prototype, {
// Shared members
//...
});
return {
DerivedDirCore: DerivedDirCore
};
}
Reusing an AngularJS Directive core code. The idea is to:
** 1. conceal the actual directive behaviour in a separate JS "class",
** 2. store that in an Angular service,
** 3. inject that service into an Angular directive,
** 4. just have the directive factory function return the constructed instance of the "class".
That is to separate the directive core code from the actual directive factory.
Then one actually wants to inherit a directive core "class" from another. It's not really a matter of JS inheritance, but more on how to inject one into the other by means of Angular modules, without actually instantiating none of them until needed,
Here are the steps to put inheritance in place:
** 1. store the base directive core code in an Angular service, by actually storing the class as a public property of the service,
** 2. inject the base code service into the derived code service
** 3. in derived code service, grab the base class as a public property and use that to build up the inheritance chain
(function () {
'use strict';
// This is just a classic implementation, with comments,
// of a 'helper' to obtain prototypical inherithance in JavaScript
// Get a dummy 'class' whose constructor has no side effects,
// so the class can be instantiated without issues, and that
// adds no members, so not to be 'transparent' inherithance-wise
function ParentWrapper() { }
function extend(baseClass, derivedClass) {
// Copy prototype from base class to wrapper
ParentWrapper.prototype = baseClass.prototype;
// Complete inherithance chain by setting wrapper as derived class prototype
derivedClass.prototype = new ParentWrapper();
// Remember the constructor property was set wrong, let's fix it
derivedClass.prototype.constructor = derivedClass;
// Allow invoking base (prototype) members
derivedClass.prototype._super = baseClass.prototype;
}
Function.prototype.inheritsFrom = function (parentClassOrObject) {
extend(parentClassOrObject, this);
}
})();
@BrainCrumbz
Copy link
Author

@Swathi-S-Sunder please have a look at the plunkr and see if that helps

@nicolasr75
Copy link

Many thanks for the plunkr!!! I think it contains some crucial points that I could not have found myself easily.
F.e. the use of $.proxy() and how to return the directive definition object.

@nhuttrung
Copy link

Thanks @BrainCrumbz.

Just a question about this.link = $.proxy(this._postLink, this); (in the file baseDirective.js)

Why do we use the $.proxy? And why don't we use the following instead?

BaseDefinition.prototype.link = function (scope, element, attr, controller) {
...
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment