new(directive): added ng:module directive for loading modules

This commit is contained in:
Misko Hevery 2011-11-08 17:40:03 -08:00
parent 4b35a59c6a
commit 085e3c611f
7 changed files with 58 additions and 27 deletions

View file

@ -1028,6 +1028,7 @@ function publishExternalAPI(angular){
'copy': copy,
'extend': extend,
'equals': equals,
'element': jqLite,
'forEach': forEach,
'injector': function(){ return createInjector(arguments, angularModule); },
'noop':noop,

View file

@ -1,9 +1,7 @@
'use strict';
publishExternalAPI(angular);
//try to bind to jquery now so that one can write angular.element().read()
//but we will rebind on bootstrap again.
bindJQuery();
publishExternalAPI(angular);

View file

@ -167,24 +167,29 @@ function createInjector(modulesToLoad, moduleRegistry) {
instance = new Constructor();
return invoke(instance, Type, locals) || instance;
};
injector.loadModule = loadModule;
return injector;
}
forEach(modulesToLoad, function(module){
if (isString(module)) {
if (moduleRegistry[module]) {
module = moduleRegistry[module];
} else {
throw Error("Module '" + module + "' is not defined!");
function loadModule(modulesToLoad){
forEach(isString(modulesToLoad) ? modulesToLoad.split(',') : modulesToLoad, function(module) {
if (isString(module)) {
if (moduleRegistry[module = trim(module)]) {
module = moduleRegistry[module];
} else {
throw Error("Module '" + module + "' is not defined!");
}
}
}
if (isFunction(module) || isArray(module)) {
$injector(module);
} else {
assertArgFn(module, 'module');
}
});
if (isFunction(module) || isArray(module)) {
$injector(module);
} else {
assertArgFn(module, 'module');
}
});
}
loadModule(modulesToLoad);
// instantiate $eager providers
// for perf we can't do forEach

View file

@ -690,8 +690,7 @@ angularDirective("ng:class-odd", ngClass(function(i){return i % 2 === 0;}));
<doc:source>
<ol ng:init="names=['John', 'Mary', 'Cate', 'Suz']">
<li ng:repeat="name in names">
<span ng:class-odd="'ng-format-negative'"
ng:class-even="'ng-input-indicator-wait'">
<span ng:class-odd="'odd'" ng:class-even="'even'">
{{name}} &nbsp; &nbsp; &nbsp;
</span>
</li>
@ -700,9 +699,9 @@ angularDirective("ng:class-odd", ngClass(function(i){return i % 2 === 0;}));
<doc:scenario>
it('should check ng:class-odd and ng:class-even', function() {
expect(element('.doc-example-live li:first span').prop('className')).
toMatch(/ng-format-negative/);
toMatch(/odd/);
expect(element('.doc-example-live li:last span').prop('className')).
toMatch(/ng-input-indicator-wait/);
toMatch(/even/);
});
</doc:scenario>
</doc:example>
@ -888,3 +887,12 @@ angularDirective("ng:cloak", function(expression, element) {
element.removeAttr('ng:cloak');
element.removeClass('ng-cloak');
});
angularDirective('ng:module', ['$value', '$injector',
function(modules, $injector) {
forEach(modules.split(','), function(module){
if (module = trim(module)) {
$injector.loadModule(module);
}
});
}]);

View file

@ -27,7 +27,11 @@ function $CompileProvider(){
}
forEach(this.linkFns, function(fn) {
try {
$injector.invoke(childScope, fn, locals);
if (isArray(fn) || fn.$inject) {
$injector.invoke(childScope, fn, locals);
} else {
fn.call(childScope, element);
}
} catch (e) {
$exceptionHandler(e);
}
@ -52,10 +56,6 @@ function $CompileProvider(){
addLinkFn:function(linkingFn) {
if (linkingFn) {
//TODO(misko): temporary hack.
if (isFunction(linkingFn) && !linkingFn.$inject) {
linkingFn.$inject = ['$element'];
}
this.linkFns.push(linkingFn);
}
},
@ -298,7 +298,9 @@ function $CompileProvider(){
fn = directiveFns[name];
if (fn) {
element.addClass('ng-directive');
template.addLinkFn((directiveFns[name]).call(selfApi, value, element));
template.addLinkFn((isArray(fn) || fn.$inject)
? $injector.invoke(selfApi, fn, {$value:value, $element: element})
: fn.call(selfApi, value, element));
}
});
}

View file

@ -535,4 +535,17 @@ describe("directive", function() {
expect(element.hasClass('bar')).toBe(true);
}));
});
describe('ng:module', function() {
it('should install the modules', inject(function($injector, $compile, $rootScope) {
var log = '';
var injector = $injector;
angular.module.a = function($injector){ log += ($injector == injector) + ';';};
angular.module.b = function($injector){ log += ($injector == injector); }
$compile('<div ng:module=" a, ,,, b "></div>')($rootScope);
expect(log).toEqual('true;true');
delete angular.module.a;
delete angular.module.b;
}));
});
});

View file

@ -11,6 +11,10 @@ angular.scenario.testing.MockAngular.prototype.reset = function() {
this.log = [];
};
angular.scenario.testing.MockAngular.prototype.element = function(e) {
return jqLite(e);
};
angular.scenario.testing.MockAngular.prototype.$browser = function() {
this.log.push('$brower()');
return this;