mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-05-28 07:23:59 +00:00
feat(injector): add $provide.decorator
This commit is contained in:
parent
5e4d59adf0
commit
4e3c05b99e
2 changed files with 155 additions and 1 deletions
|
|
@ -251,7 +251,8 @@ function createInjector(modulesToLoad, moduleRegistry) {
|
||||||
value('$provide', {
|
value('$provide', {
|
||||||
service: service,
|
service: service,
|
||||||
factory: factory,
|
factory: factory,
|
||||||
value: value
|
value: value,
|
||||||
|
decorator: decorator
|
||||||
});
|
});
|
||||||
|
|
||||||
loadModule(modulesToLoad);
|
loadModule(modulesToLoad);
|
||||||
|
|
@ -274,6 +275,18 @@ function createInjector(modulesToLoad, moduleRegistry) {
|
||||||
|
|
||||||
function value(name, value) { factory(name, valueFn(value)); }
|
function value(name, value) { factory(name, valueFn(value)); }
|
||||||
|
|
||||||
|
function decorator(name, decorFn) {
|
||||||
|
var origProvider = cache['#' + name + providerSuffix];
|
||||||
|
if (!origProvider) throw Error("Can't find provider for: " + name);
|
||||||
|
if (cache['#' + name]) throw Error("Service " + name + " already instantiated, can't decorate!");
|
||||||
|
var orig$get = origProvider.$get;
|
||||||
|
origProvider.$get = function() {
|
||||||
|
var origInstance = $injector.invoke(origProvider, orig$get);
|
||||||
|
return $injector.invoke(null, decorFn, {$delegate: origInstance});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function getService(value) {
|
function getService(value) {
|
||||||
if (typeof value !== 'string') {
|
if (typeof value !== 'string') {
|
||||||
throw Error('Service name expected');
|
throw Error('Service name expected');
|
||||||
|
|
|
||||||
|
|
@ -280,6 +280,147 @@ describe('injector', function() {
|
||||||
}]).get('value')).toEqual('abc');
|
}]).get('value')).toEqual('abc');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('decorator', function() {
|
||||||
|
var log, injector;
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
log = [];
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('should be called with the original instance', function() {
|
||||||
|
injector = createInjector([function($provide) {
|
||||||
|
$provide.value('myService', function(val) {
|
||||||
|
log.push('myService:' + val);
|
||||||
|
return 'origReturn';
|
||||||
|
});
|
||||||
|
|
||||||
|
$provide.decorator('myService', function($delegate) {
|
||||||
|
return function(val) {
|
||||||
|
log.push('myDecoratedService:' + val);
|
||||||
|
var origVal = $delegate('decInput');
|
||||||
|
return 'dec+' + origVal;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}]);
|
||||||
|
|
||||||
|
var out = injector.get('myService')('input');
|
||||||
|
log.push(out);
|
||||||
|
expect(log.join('; ')).
|
||||||
|
toBe('myDecoratedService:input; myService:decInput; dec+origReturn');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('should allow multiple decorators to be applied to a service', function() {
|
||||||
|
injector = createInjector([function($provide) {
|
||||||
|
$provide.value('myService', function(val) {
|
||||||
|
log.push('myService:' + val);
|
||||||
|
return 'origReturn';
|
||||||
|
});
|
||||||
|
|
||||||
|
$provide.decorator('myService', function($delegate) {
|
||||||
|
return function(val) {
|
||||||
|
log.push('myDecoratedService1:' + val);
|
||||||
|
var origVal = $delegate('decInput1');
|
||||||
|
return 'dec1+' + origVal;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
$provide.decorator('myService', function($delegate) {
|
||||||
|
return function(val) {
|
||||||
|
log.push('myDecoratedService2:' + val);
|
||||||
|
var origVal = $delegate('decInput2');
|
||||||
|
return 'dec2+' + origVal;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}]);
|
||||||
|
|
||||||
|
var out = injector.get('myService')('input');
|
||||||
|
log.push(out);
|
||||||
|
expect(log).toEqual(['myDecoratedService2:input',
|
||||||
|
'myDecoratedService1:decInput2',
|
||||||
|
'myService:decInput1',
|
||||||
|
'dec2+dec1+origReturn']);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('should decorate services with dependencies', function() {
|
||||||
|
injector = createInjector([function($provide) {
|
||||||
|
$provide.value('dep1', 'dependency1');
|
||||||
|
|
||||||
|
$provide.factory('myService', ['dep1', function(dep1) {
|
||||||
|
return function(val) {
|
||||||
|
log.push('myService:' + val + ',' + dep1);
|
||||||
|
return 'origReturn';
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
|
||||||
|
$provide.decorator('myService', function($delegate) {
|
||||||
|
return function(val) {
|
||||||
|
log.push('myDecoratedService:' + val);
|
||||||
|
var origVal = $delegate('decInput');
|
||||||
|
return 'dec+' + origVal;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}]);
|
||||||
|
|
||||||
|
var out = injector.get('myService')('input');
|
||||||
|
log.push(out);
|
||||||
|
expect(log.join('; ')).
|
||||||
|
toBe('myDecoratedService:input; myService:decInput,dependency1; dec+origReturn');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('should allow for decorators to be injectable', function() {
|
||||||
|
injector = createInjector([function($provide) {
|
||||||
|
$provide.value('dep1', 'dependency1');
|
||||||
|
|
||||||
|
$provide.factory('myService', function() {
|
||||||
|
return function(val) {
|
||||||
|
log.push('myService:' + val);
|
||||||
|
return 'origReturn';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$provide.decorator('myService', function($delegate, dep1) {
|
||||||
|
return function(val) {
|
||||||
|
log.push('myDecoratedService:' + val + ',' + dep1);
|
||||||
|
var origVal = $delegate('decInput');
|
||||||
|
return 'dec+' + origVal;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}]);
|
||||||
|
|
||||||
|
var out = injector.get('myService')('input');
|
||||||
|
log.push(out);
|
||||||
|
expect(log.join('; ')).
|
||||||
|
toBe('myDecoratedService:input,dependency1; myService:decInput; dec+origReturn');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('should complain if the service to be decorated was already instantiated', function() {
|
||||||
|
injector = createInjector([function($provide, $injector) {
|
||||||
|
$provide.value('myService', function(val) {
|
||||||
|
log.push('myService:' + val);
|
||||||
|
return 'origReturn';
|
||||||
|
});
|
||||||
|
|
||||||
|
$injector.get('myService');
|
||||||
|
|
||||||
|
expect(function() {
|
||||||
|
$provide.decorator('myService', function($delegate) {
|
||||||
|
return function(val) {
|
||||||
|
log.push('myDecoratedService:' + val);
|
||||||
|
var origVal = $delegate('decInput');
|
||||||
|
return 'dec+' + origVal;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}).toThrow("Service myService already instantiated, can't decorate!");
|
||||||
|
}]);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue