Skip to content

Instantly share code, notes, and snippets.

@hgwood
Last active August 29, 2015 14:15
Show Gist options
  • Save hgwood/880297b0851eb49a5c27 to your computer and use it in GitHub Desktop.
Save hgwood/880297b0851eb49a5c27 to your computer and use it in GitHub Desktop.
Another example of integrating CommonJS and Angular's DI (replaces diverge.js from https://gist.github.com/hgwood/2f9f11e7eff1f144d675). This one monkey patches $injector and $controllerProvider to apply custom logic when resolving component names.
"use strict";
var _ = require("lodash");
var angular = require("angularjs");
module.exports = function diverge(rootModuleName, ngComponents) {
angular.module(rootModuleName, [])
.config(decorateInjector)
.config(decorateControllerProvider);
function decorateInjector($injector, $provide) {
monkeyPatch($injector, "get", function (get, name, caller) {
return findOwnComponent(name, ngComponents) || get(name, caller);
});
function findOwnComponent(name) {
return _(ngComponents)
.select(function (ngComponent) {
return _.startsWith(name, ngComponent.name);
})
.map(function (ngComponent) {
return _.assign(getNgNameAndType(ngComponent.name), {constructor: ngComponent});
})
.map(function (component) {
return $provide[component.type](component.name, component.constructor);
})
.first();
}
}
function decorateControllerProvider($controllerProvider) {
monkeyPatch($controllerProvider.$get, $controllerProvider.$get.length - 1, function ($get, $injector) {
return decorate($injector.invoke($get), function ($controller, constructor, locals, later, ident) {
registerOwnController(getControllerName(constructor), ngComponents);
return $controller(constructor, locals, later, ident);
});
});
function registerOwnController(name) {
_(ngComponents)
.select(function (ngComponent) {
return _.startsWith(name, ngComponent.name);
})
.each(function (ngComponent) {
$controllerProvider.register(name, ngComponent);
})
.value();
}
}
};
function getControllerName(ngControllerConstructor) {
return _.contains(ngControllerConstructor, "as") ?
ngControllerConstructor.split(" ")[0] :
ngControllerConstructor;
}
function getNgNameAndType(exportedFunctionName) {
var match = exportedFunctionName.match(/(.*)(Controller|Service|Factory|Filter|Directive)$/);
return {name: match[0], type: match[2].toLowerCase()};
}
function decorate(delegate, decorator) {
return _.partial(decorator, delegate);
}
function monkeyPatch(service, method, decorator) {
service[method] = decorate(service[method], decorator);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment