aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMisko Hevery2012-01-13 14:19:10 -0800
committerMisko Hevery2012-01-13 14:28:43 -0800
commit5cdfe45aa3e50fabad44009c1b8511253c6e4915 (patch)
treeeb921be6b173d5fd3a9cd1f0a95b5e1cace37fd8
parent16a40c626fc3da688596928afa028a596204a683 (diff)
downloadangular.js-5cdfe45aa3e50fabad44009c1b8511253c6e4915.tar.bz2
feat(module): add runtime block
-rw-r--r--src/Injector.js12
-rw-r--r--src/angular-mocks.js2
-rw-r--r--src/loader.js48
-rw-r--r--test/InjectorSpec.js12
-rw-r--r--test/loaderSpec.js14
5 files changed, 67 insertions, 21 deletions
diff --git a/src/Injector.js b/src/Injector.js
index c9901513..cebc6eed 100644
--- a/src/Injector.js
+++ b/src/Injector.js
@@ -272,7 +272,7 @@ function createInjector(modulesToLoad) {
}));
- loadModules(modulesToLoad);
+ forEach(loadModules(modulesToLoad), function(fn) { instanceInjector.invoke(fn || noop); });
return instanceInjector;
@@ -318,15 +318,16 @@ function createInjector(modulesToLoad) {
// Module Loading
////////////////////////////////////
function loadModules(modulesToLoad){
+ var runBlocks = [];
forEach(modulesToLoad, function(module) {
if (loadedModules.get(module)) return;
loadedModules.put(module, true);
if (isString(module)) {
var moduleFn = angularModule(module);
- loadModules(moduleFn.requires);
+ runBlocks = runBlocks.concat(loadModules(moduleFn.requires)).concat(moduleFn._runBlocks);
try {
- for(var invokeQueue = moduleFn.invokeQueue, i = 0, ii = invokeQueue.length; i < ii; i++) {
+ for(var invokeQueue = moduleFn._invokeQueue, i = 0, ii = invokeQueue.length; i < ii; i++) {
var invokeArgs = invokeQueue[i],
provider = invokeArgs[0] == '$injector'
? providerInjector
@@ -340,14 +341,14 @@ function createInjector(modulesToLoad) {
}
} else if (isFunction(module)) {
try {
- providerInjector.invoke(module);
+ runBlocks.push(providerInjector.invoke(module));
} catch (e) {
if (e.message) e.message += ' from ' + module;
throw e;
}
} else if (isArray(module)) {
try {
- providerInjector.invoke(module);
+ runBlocks.push(providerInjector.invoke(module));
} catch (e) {
if (e.message) e.message += ' from ' + String(module[module.length - 1]);
throw e;
@@ -356,6 +357,7 @@ function createInjector(modulesToLoad) {
assertArgFn(module, 'module');
}
});
+ return runBlocks;
}
////////////////////////////////////
diff --git a/src/angular-mocks.js b/src/angular-mocks.js
index 3c74cf9b..3bc31989 100644
--- a/src/angular-mocks.js
+++ b/src/angular-mocks.js
@@ -1287,7 +1287,7 @@ angular.module('ngMock', ['ng']).service({
* Currently there is only one mock present in this module -
* the {@link angular.module.ngMockE2E.$httpBackend e2e $httpBackend} mock.
*/
-angular.module('ngMockE2E', ['ng']).init(function($provide) {
+angular.module('ngMockE2E', ['ng']).config(function($provide) {
$provide.decorator('$httpBackend', angular.mock.e2e.$httpBackendDecorator);
});
diff --git a/src/loader.js b/src/loader.js
index 3d5edd31..e6662aae 100644
--- a/src/loader.js
+++ b/src/loader.js
@@ -58,7 +58,7 @@ function setupModuleLoader(window) {
* {@link angular.Module#init Module.init()}.
* @return {angular.Module}
*/
- return function module(name, requires, initFn) {
+ return function module(name, requires, configFn) {
if (requires && modules.hasOwnProperty(name)) {
modules[name] = null;
}
@@ -70,10 +70,17 @@ function setupModuleLoader(window) {
/** @type {!Array.<Array.<*>>} */
var invokeQueue = [];
- var init = invokeLater('$injector', 'invoke');
+ /** @type {!Array.<Function>} */
+ var runBlocks = [];
+
+ var config = invokeLater('$injector', 'invoke');
/** @type {angular.Module} */
var moduleInstance = {
+ // Private state
+ _invokeQueue: invokeQueue,
+ _runBlocks: runBlocks,
+
/**
* @ngdoc property
* @name angular.Module#requires
@@ -83,7 +90,16 @@ function setupModuleLoader(window) {
* Holds the list of modules which the injector will load before the current module is loaded.
*/
requires: requires,
- invokeQueue: invokeQueue,
+
+ /**
+ * @ngdoc property
+ * @name angular.Module#name
+ * @propertyOf angular.Module
+ * @returns {string} Name of the module.
+ * @description
+ */
+ name: name,
+
/**
* @ngdoc method
@@ -131,18 +147,32 @@ function setupModuleLoader(window) {
/**
* @ngdoc method
- * @name angular.Module#init
+ * @name angular.Module#config
* @methodOf angular.Module
- * @param {Function} initializationFn Execute this function on module load, allowing it to do any
- * service configuration..
+ * @param {Function} initializationFn Execute this function on module load. Useful for
+ * service configuration.
* @description
* Use this method to register work which needs to be performed on module loading.
*/
- init: init
+ config: config,
+
+ /**
+ * @ngdoc method
+ * @name angular.Module#run
+ * @methodOf angular.Module
+ * @param {Function} initializationFn Execute this function after injector creation.
+ * Useful for application initialization.
+ * @description
+ * Use this method to register work which needs to be performed on module loading.
+ */
+ run: function(block) {
+ runBlocks.push(block);
+ return this;
+ }
};
- if (initFn) {
- init(initFn);
+ if (configFn) {
+ config(configFn);
}
return moduleInstance;
diff --git a/test/InjectorSpec.js b/test/InjectorSpec.js
index 4817dc32..c6e9f178 100644
--- a/test/InjectorSpec.js
+++ b/test/InjectorSpec.js
@@ -247,6 +247,18 @@ describe('injector', function() {
expect(log).toEqual('abc');
});
+ it('should execute runBlocks after injector creation', function() {
+ var log = '';
+ angular.module('a', [], function(){ log += 'a'; }).run(function() { log += 'A'; });
+ angular.module('b', ['a'], function(){ log += 'b'; }).run(function() { log += 'B'; });
+ createInjector([
+ 'b',
+ valueFn(function() { log += 'C'; }),
+ [valueFn(function() { log += 'D'; })]
+ ]);
+ expect(log).toEqual('abABCD');
+ });
+
describe('$provide', function() {
describe('value', function() {
it('should configure $provide values', function() {
diff --git a/test/loaderSpec.js b/test/loaderSpec.js
index e419a198..ac48c34e 100644
--- a/test/loaderSpec.js
+++ b/test/loaderSpec.js
@@ -27,26 +27,28 @@ describe('module loader', function() {
it('should record calls', function() {
var otherModule = window.angular.module('other', []);
- otherModule.init('otherInit');
+ otherModule.config('otherInit');
- var myModule = window.angular.module('my', ['other'], 'init');
+ var myModule = window.angular.module('my', ['other'], 'config');
- myModule.
+ expect(myModule.
service('sk', 'sv').
factory('fk', 'fv').
value('k', 'v').
filter('f', 'ff').
- init('init2');
+ config('init2').
+ run('runBlock')).toBe(myModule);
expect(myModule.requires).toEqual(['other']);
- expect(myModule.invokeQueue).toEqual([
- ['$injector', 'invoke', ['init'] ],
+ expect(myModule._invokeQueue).toEqual([
+ ['$injector', 'invoke', ['config'] ],
['$provide', 'service', ['sk', 'sv'] ],
['$provide', 'factory', ['fk', 'fv'] ],
['$provide', 'value', ['k', 'v'] ],
['$filterProvider', 'register', ['f', 'ff'] ],
['$injector', 'invoke', ['init2'] ]
]);
+ expect(myModule._runBlocks).toEqual(['runBlock']);
});