diff options
| author | Igor Minar | 2011-01-04 00:46:25 -0800 |
|---|---|---|
| committer | Igor Minar | 2011-01-04 16:40:41 -0800 |
| commit | 3ea5941f0e51c57f55071a85f2033c23c99847c0 (patch) | |
| tree | 74b8b20178e96f13c5f3550740e35dcb68642a8a | |
| parent | d0270d92568e1b7c762b42a0ee0712b65d9acc5c (diff) | |
| download | angular.js-3ea5941f0e51c57f55071a85f2033c23c99847c0.tar.bz2 | |
removing support for 'eager-published' services
| -rw-r--r-- | CHANGELOG.md | 33 | ||||
| -rw-r--r-- | src/Injector.js | 6 | ||||
| -rw-r--r-- | src/services.js | 13 | ||||
| -rw-r--r-- | src/validators.js | 10 | ||||
| -rw-r--r-- | src/widgets.js | 2 | ||||
| -rw-r--r-- | test/BinderTest.js | 16 | ||||
| -rw-r--r-- | test/InjectorSpec.js | 16 | ||||
| -rw-r--r-- | test/ValidatorsTest.js | 2 | ||||
| -rw-r--r-- | test/servicesSpec.js | 46 |
9 files changed, 83 insertions, 61 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index b9227eb5..ed9d4fb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,39 @@ # <angular/> 0.9.9 time-shift (in-progress) # +### Performance +- $location and $cookies services are now lazily initialized to avoid the polling overhead when + not needed. + ### Breaking changes - - Many of the services are now lazy created instead of 'eager-publish'. You can get these - services back into the root scope by adding ng:init="$location = $inject('$location')" - in your view. The services effected are: + - Support for 'eager-published' services was removed. This change was done to make explicit + dependency declaration always required in order to allow making relatively expensive services + lazily initialized (e.g. $cookie, $location), as well as remove 'magic' and reduce unnecessary + scope namespace pollution. + + Complete list of affected services: + - $location - $route - $cookies + - $window + - $document + - $exceptionHandler + - $invalidWidgets + + To temporarily preserve the 'eager-published' status for these services, you may use `ng:init` + (e.g. `ng:init="$location = $inject('$location'), ...`) in the view or more correctly create + a service like this: + + angular.service('published-svc-shim', function() { + this.$location = this.$inject('$location'); + this.$route = this.$inject('$route'); + this.$cookies = this.$inject('$cookies'); + this.$window = this.$inject('$window'); + this.$document = this.$inject('$document'); + this.$exceptionHandler = this.$inject('$exceptionHandler'); + this.$invalidWidgets = this.$inject('$invalidWidgets'); + }, {$creation: 'eager'}); + # <angular/> 0.9.8 astral-projection (2010-12-23) # diff --git a/src/Injector.js b/src/Injector.js index 6fc466b9..c819d4f0 100644 --- a/src/Injector.js +++ b/src/Injector.js @@ -58,9 +58,9 @@ function createInjector(providerScope, providers, cache) { creation = provider.$creation; if (creation == 'eager') { inject(name); - } - if (creation == 'eager-published') { - setter(value, name, inject(name)); + } else { + if (isDefined(creation)) + throw "Unknown $creation value '" + creation + "' for service " + name; } }); } else { diff --git a/src/services.js b/src/services.js index 5356d612..e77baf38 100644 --- a/src/services.js +++ b/src/services.js @@ -1,8 +1,7 @@ var URL_MATCH = /^(file|ftp|http|https):\/\/(\w+:{0,1}\w*@)?([\w\.-]*)(:([0-9]+))?(\/[^\?#]*)?(\?([^#]*))?(#(.*))?$/, HASH_MATCH = /^([^\?]*)?(\?([^\?]*))?$/, DEFAULT_PORTS = {'http': 80, 'https': 443, 'ftp':21}, - EAGER = 'eager', - EAGER_PUBLISHED = EAGER + '-published'; + EAGER = 'eager'; function angularServiceInject(name, fn, inject, eager) { angularService(name, fn, {$inject:inject, $creation:eager}); @@ -26,7 +25,7 @@ function angularServiceInject(name, fn, inject, eager) { <input ng:init="greeting='Hello World!'" type="text" name="greeting" /> <button ng:click="$window.alert(greeting)">ALERT</button> */ -angularServiceInject("$window", bind(window, identity, window), [], EAGER_PUBLISHED); +angularServiceInject("$window", bind(window, identity, window), [], EAGER); /** * @workInProgress @@ -39,7 +38,7 @@ angularServiceInject("$window", bind(window, identity, window), [], EAGER_PUBLIS */ angularServiceInject("$document", function(window){ return jqLite(window.document); -}, ['$window'], EAGER_PUBLISHED); +}, ['$window'], EAGER); /** * @workInProgress @@ -382,7 +381,7 @@ angularServiceInject("$log", function($window){ return logFn; } } -}, ['$window'], EAGER_PUBLISHED); +}, ['$window'], EAGER); /** * @workInProgress @@ -406,7 +405,7 @@ angularServiceInject('$exceptionHandler', function($log){ return function(e) { $log.error(e); }; -}, ['$log'], EAGER_PUBLISHED); +}, ['$log'], EAGER); /** * @workInProgress @@ -531,7 +530,7 @@ angularServiceInject("$invalidWidgets", function(){ } return invalidWidgets; -}, [], EAGER_PUBLISHED); +}, [], EAGER); diff --git a/src/validators.js b/src/validators.js index 8e288882..b55db341 100644 --- a/src/validators.js +++ b/src/validators.js @@ -382,10 +382,12 @@ extend(angularValidator, { cache.current = input; - var inputState = cache.inputs[input]; + var inputState = cache.inputs[input], + $invalidWidgets = scope.$inject('$invalidWidgets'); + if (!inputState) { cache.inputs[input] = inputState = { inFlight: true }; - scope.$invalidWidgets.markInvalid(scope.$element); + $invalidWidgets.markInvalid(scope.$element); element.addClass('ng-input-indicator-wait'); asynchronousFn(input, function(error, data) { inputState.response = data; @@ -393,14 +395,14 @@ extend(angularValidator, { inputState.inFlight = false; if (cache.current == input) { element.removeClass('ng-input-indicator-wait'); - scope.$invalidWidgets.markValid(element); + $invalidWidgets.markValid(element); } element.data($$validate)(); scope.$root.$eval(); }); } else if (inputState.inFlight) { // request in flight, mark widget invalid, but don't show it to user - scope.$invalidWidgets.markInvalid(scope.$element); + $invalidWidgets.markInvalid(scope.$element); } else { (updateFn||noop)(inputState.response); } diff --git a/src/widgets.js b/src/widgets.js index 532627eb..a09ee29d 100644 --- a/src/widgets.js +++ b/src/widgets.js @@ -271,7 +271,7 @@ function valueAccessor(scope, element) { formatterName = element.attr('ng:format') || NOOP, formatter = angularFormatter(formatterName), format, parse, lastError, required, - invalidWidgets = scope.$invalidWidgets || {markValid:noop, markInvalid:noop}; + invalidWidgets = scope.$inject('$invalidWidgets') || {markValid:noop, markInvalid:noop}; if (!validator) throw "Validator named '" + validatorName + "' not found."; if (!formatter) throw "Formatter named '" + formatterName + "' not found."; format = formatter.format; diff --git a/test/BinderTest.js b/test/BinderTest.js index 58081f25..c5c81ee9 100644 --- a/test/BinderTest.js +++ b/test/BinderTest.js @@ -515,38 +515,38 @@ BinderTest.prototype.testValidateForm = function() { var items = [{}, {}]; c.scope.$set("items", items); c.scope.$eval(); - assertEquals(3, c.scope.$get("$invalidWidgets.length")); + assertEquals(3, c.scope.$inject('$invalidWidgets').length); c.scope.$set('name', ''); c.scope.$eval(); - assertEquals(3, c.scope.$get("$invalidWidgets.length")); + assertEquals(3, c.scope.$inject('$invalidWidgets').length); c.scope.$set('name', ' '); c.scope.$eval(); - assertEquals(3, c.scope.$get("$invalidWidgets.length")); + assertEquals(3, c.scope.$inject('$invalidWidgets').length); c.scope.$set('name', 'abc'); c.scope.$eval(); - assertEquals(2, c.scope.$get("$invalidWidgets.length")); + assertEquals(2, c.scope.$inject('$invalidWidgets').length); items[0].name = 'abc'; c.scope.$eval(); - assertEquals(1, c.scope.$get("$invalidWidgets.length")); + assertEquals(1, c.scope.$inject('$invalidWidgets').length); items[1].name = 'abc'; c.scope.$eval(); - assertEquals(0, c.scope.$get("$invalidWidgets.length")); + assertEquals(0, c.scope.$inject('$invalidWidgets').length); }; BinderTest.prototype.testValidateOnlyVisibleItems = function(){ var c = this.compile('<div><input name="name" ng:required><input ng:show="show" name="name" ng:required></div>', undefined, jqLite(document.body)); c.scope.$set("show", true); c.scope.$eval(); - assertEquals(2, c.scope.$get("$invalidWidgets.length")); + assertEquals(2, c.scope.$inject('$invalidWidgets').length); c.scope.$set("show", false); c.scope.$eval(); - assertEquals(1, c.scope.$invalidWidgets.visible()); + assertEquals(1, c.scope.$inject('$invalidWidgets').visible()); }; BinderTest.prototype.testDeleteAttributeIfEvaluatesFalse = function() { diff --git a/test/InjectorSpec.js b/test/InjectorSpec.js index ba0f27f7..275d98ff 100644 --- a/test/InjectorSpec.js +++ b/test/InjectorSpec.js @@ -53,19 +53,9 @@ describe('injector', function(){ it('should autostart eager services', function(){ var log = ''; - providers('eager', function(){log += 'eager;';}, {$creation: 'eager'}); + providers('eager', function(){log += 'eager;'; return 'foo'}, {$creation: 'eager'}); inject(); expect(log).toEqual('eager;'); - expect(scope.eager).not.toBeDefined(); + expect(inject('eager')).toBe('foo'); }); - - - it('should return a list of published objects', function(){ - var log = ''; - providers('eager', function(){log += 'eager;'; return 'pub'; }, {$creation: 'eager-published'}); - inject(); - expect(log).toEqual('eager;'); - expect(scope.eager).toEqual('pub'); - - }); -});
\ No newline at end of file +}); diff --git a/test/ValidatorsTest.js b/test/ValidatorsTest.js index f740c7b2..d6df7184 100644 --- a/test/ValidatorsTest.js +++ b/test/ValidatorsTest.js @@ -128,7 +128,7 @@ describe('Validator:asynchronous', function(){ it("should not make second request to same value", function(){ asynchronous.call(self, "kai", function(v,f){value=v; fn=f;}); expect(value).toEqual('kai'); - expect(self.$invalidWidgets[0]).toEqual(self.$element); + expect(self.$inject('$invalidWidgets')[0]).toEqual(self.$element); var spy = jasmine.createSpy(); asynchronous.call(self, "kai", spy); diff --git a/test/servicesSpec.js b/test/servicesSpec.js index 014acae4..e7bf39cb 100644 --- a/test/servicesSpec.js +++ b/test/servicesSpec.js @@ -24,7 +24,7 @@ describe("service", function(){ it("should inject $window", function(){ - expect(scope.$window).toEqual(window); + expect(scope.$inject('$window')).toEqual(window); }); xit('should add stylesheets', function(){ @@ -44,11 +44,12 @@ describe("service", function(){ function warn(){ logger+= 'warn;'; } function info(){ logger+= 'info;'; } function error(){ logger+= 'error;'; } - var scope = createScope({}, angularService, {$window: {console:{log:log, warn:warn, info:info, error:error}}, $document:[{cookie:''}]}); - scope.$log.log(); - scope.$log.warn(); - scope.$log.info(); - scope.$log.error(); + var scope = createScope({}, angularService, {$window: {console:{log:log, warn:warn, info:info, error:error}}, $document:[{cookie:''}]}), + $log = scope.$inject('$log'); + $log.log(); + $log.warn(); + $log.info(); + $log.error(); expect(logger).toEqual('log;warn;info;error;'); }); @@ -56,19 +57,21 @@ describe("service", function(){ var logger = ""; function log(){ logger+= 'log;'; } var scope = createScope({}, angularService, {$window: {console:{log:log}}, $document:[{cookie:''}]}); - scope.$log.log(); - scope.$log.warn(); - scope.$log.info(); - scope.$log.error(); + var $log = scope.$inject('$log'); + $log.log(); + $log.warn(); + $log.info(); + $log.error(); expect(logger).toEqual('log;log;log;log;'); }); it('should use noop if no console', function(){ - var scope = createScope({}, angularService, {$window: {}, $document:[{cookie:''}]}); - scope.$log.log(); - scope.$log.warn(); - scope.$log.info(); - scope.$log.error(); + var scope = createScope({}, angularService, {$window: {}, $document:[{cookie:''}]}), + $log = scope.$inject('$log'); + $log.log(); + $log.warn(); + $log.info(); + $log.error(); }); describe('Error', function(){ @@ -112,7 +115,7 @@ describe("service", function(){ it('should log errors', function(){ var error = ''; $log.error = function(m) { error += m; }; - scope.$exceptionHandler('myError'); + scope.$inject('$exceptionHandler')('myError'); expect(error).toEqual('myError'); }); }); @@ -263,25 +266,26 @@ describe("service", function(){ scope = compile('<input name="price" ng:required ng:validate="number"></input>'); jqLite(document.body).append(scope.$element); scope.$init(); - expect(scope.$invalidWidgets.length).toEqual(1); + var $invalidWidgets = scope.$inject('$invalidWidgets'); + expect($invalidWidgets.length).toEqual(1); scope.price = 123; scope.$eval(); - expect(scope.$invalidWidgets.length).toEqual(0); + expect($invalidWidgets.length).toEqual(0); scope.$element.remove(); scope.price = 'abc'; scope.$eval(); - expect(scope.$invalidWidgets.length).toEqual(0); + expect($invalidWidgets.length).toEqual(0); jqLite(document.body).append(scope.$element); scope.price = 'abcd'; //force revalidation, maybe this should be done automatically? scope.$eval(); - expect(scope.$invalidWidgets.length).toEqual(1); + expect($invalidWidgets.length).toEqual(1); jqLite(document.body).html(''); scope.$eval(); - expect(scope.$invalidWidgets.length).toEqual(0); + expect($invalidWidgets.length).toEqual(0); }); }); |
