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);      });    });  | 
