diff options
| -rw-r--r-- | src/Angular.js | 10 | ||||
| -rw-r--r-- | src/Compiler.js | 1 | ||||
| -rw-r--r-- | src/Validators.js | 31 | ||||
| -rw-r--r-- | src/Widgets.js | 8 | ||||
| -rw-r--r-- | test/ValidatorsTest.js | 27 | ||||
| -rw-r--r-- | test/widgetsSpec.js | 4 | 
6 files changed, 50 insertions, 31 deletions
diff --git a/src/Angular.js b/src/Angular.js index 12293ddb..e49eb9a9 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -228,6 +228,16 @@ function escapeHtml(html) {        replace(/>/g, '>');  } +function elementDecorateError(element, error) { +  if (error) { +    element.addClass(NG_VALIDATION_ERROR); +    element.attr(NG_ERROR, error); +  } else { +    element.removeClass(NG_VALIDATION_ERROR); +    element.removeAttr(NG_ERROR); +  } +} +  function escapeAttr(html) {    if (!html || !html.replace)      return html; diff --git a/src/Compiler.js b/src/Compiler.js index 923f7b2f..e97fb112 100644 --- a/src/Compiler.js +++ b/src/Compiler.js @@ -93,6 +93,7 @@ Compiler.prototype = {      rawElement = jqLite(rawElement);      var template = this.templatize(rawElement) || new Template();      return function(element, parentScope){ +      element = jqLite(element);        parentScope = parentScope || {};        var scope = createScope(parentScope);        parentScope.$root = parentScope.$root || scope; diff --git a/src/Validators.js b/src/Validators.js index 662145c0..ecf21a01 100644 --- a/src/Validators.js +++ b/src/Validators.js @@ -82,29 +82,30 @@ foreach({    },    'asynchronous': function(text, asynchronousFn) { -    var stateKey = '$validateState'; -    var lastKey = '$lastKey'; -    var obj = this['$element']; -    var stateCache = obj[stateKey] = obj[stateKey] || {}; -    var state = stateCache[text]; -    var updateView = this['$updateView']; -    obj[lastKey] = text; +    var element = this['$element']; +    var cache = element.data('$validateState'); +    if (!cache) { +      cache = { state: {}}; +      element.data('$validateState', cache); +    } +    var state = cache.state[text]; +    cache.lastKey = text;      if (state === undefined) {        // we have never seen this before, Request it -      jqLite(obj).addClass('ng-input-indicator-wait'); -      state = stateCache[text] = null; -      asynchronousFn(text, function(error){ -        state = stateCache[text] = error ? error : false; -        if (stateCache[obj[lastKey]] !== null) { -          jqLite(obj).removeClass('ng-input-indicator-wait'); +      element.addClass('ng-input-indicator-wait'); +      state = cache.state[text] = null; +      (asynchronousFn || noop)(text, function(error){ +        state = cache.state[text] = error ? error : false; +        if (cache.state[cache.lastKey] !== null) { +          element.removeClass('ng-input-indicator-wait');          } -        updateView(); +        elementDecorateError(element, error);        });      }      if (state === null){        // request in flight, mark widget invalid, but don't show it to user -      this['$invalidWidgets'].push(this.$element); +      (this['$invalidWidgets']||[]).push(this.$element);      }      return state;    } diff --git a/src/Widgets.js b/src/Widgets.js index b5222ac7..870468d3 100644 --- a/src/Widgets.js +++ b/src/Widgets.js @@ -28,13 +28,7 @@ function valueAccessor(scope, element) {    function validate(value) {      var error = required && !trim(value) ? "Required" : validator({self:scope, scope:{get:scope.$get, set:scope.$set}}, value);      if (error !== lastError) { -      if (error) { -        element.addClass(NG_VALIDATION_ERROR); -        element.attr(NG_ERROR, error); -      } else { -        element.removeClass(NG_VALIDATION_ERROR); -        element.removeAttr(NG_ERROR); -      } +      elementDecorateError(element, error);        lastError = error;      }      return value; diff --git a/test/ValidatorsTest.js b/test/ValidatorsTest.js index 971ff0bb..37be526d 100644 --- a/test/ValidatorsTest.js +++ b/test/ValidatorsTest.js @@ -91,24 +91,35 @@ describe('Validator:asynchronous', function(){      value = null;      fn = null;      self = { -        $element:jqLite('<input />')[0], +        $element:jqLite('<input />'),          $invalidWidgets:[],          $updateView: noop      };    }); -  xit('should make a request and show spinner', function(){ -    var x = compile('<input name="name" ng-validate="asynchronous:asyncFn"/>'); -    var asyncFn = function(v,f){value=v; fn=f;}; -    var input = x.node.find(":input"); -    x.scope.$set("asyncFn", asyncFn); -    x.scope.$set("name", "misko"); -    x.scope.$eval(); +  afterEach(function(){ +    if (self.$element) self.$element.remove(); +    var oldCache = jqCache; +    jqCache = {}; +    expect(size(oldCache)).toEqual(0); +  }); + +  it('should make a request and show spinner', function(){ +    var value, fn; +    var scope = angular.compile('<input type="text" name="name" ng-validate="asynchronous:asyncFn"/>'); +    scope.$init(); +    var input = scope.$element; +    scope.asyncFn = function(v,f){ +      value=v; fn=f; +    }; +    scope.name = "misko"; +    scope.$eval();      expect(value).toEqual('misko');      expect(input.hasClass('ng-input-indicator-wait')).toBeTruthy();      fn("myError");      expect(input.hasClass('ng-input-indicator-wait')).toBeFalsy();      expect(input.attr('ng-error')).toEqual("myError"); +    scope.$element.remove();    });    it("should not make second request to same value", function(){ diff --git a/test/widgetsSpec.js b/test/widgetsSpec.js index dd65b5bd..152b01f3 100644 --- a/test/widgetsSpec.js +++ b/test/widgetsSpec.js @@ -15,7 +15,9 @@ describe("input widget", function(){    afterEach(function(){      if (element) element.remove(); -    expect(size(jqCache)).toEqual(0); +    var oldCache = jqCache; +    jqCache = {}; +    expect(size(oldCache)).toEqual(0);    });    it('should input-text auto init and handle keyup/change events', function(){  | 
