mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-17 07:40:22 +00:00
seperatio validation and exception handling
This commit is contained in:
parent
a8aa5af413
commit
e0ad7dfcd4
9 changed files with 36 additions and 37 deletions
27
angular-debug.js
vendored
27
angular-debug.js
vendored
|
|
@ -34,7 +34,6 @@ var consoleNode,
|
|||
PRIORITY_WATCH = -1000,
|
||||
PRIORITY_LAST = 99999,
|
||||
NOOP = 'noop',
|
||||
NG_ERROR = 'ng-error',
|
||||
NG_EXCEPTION = 'ng-exception',
|
||||
NG_VALIDATION_ERROR = 'ng-validation-error',
|
||||
jQuery = window['jQuery'] || window['$'], // weirdness to make IE happy
|
||||
|
|
@ -283,10 +282,10 @@ function elementError(element, type, error) {
|
|||
}
|
||||
if (error) {
|
||||
element.addClass(type);
|
||||
element.attr(NG_ERROR, error);
|
||||
element.attr(type, error);
|
||||
} else {
|
||||
element.removeClass(type);
|
||||
element.removeAttr(NG_ERROR);
|
||||
element.removeAttr(type);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1222,16 +1221,7 @@ Parser.prototype = {
|
|||
for ( var i = 0; i < argsFn.length; i++) {
|
||||
args.push(argsFn[i](self));
|
||||
}
|
||||
var pipeThis = function(){
|
||||
var _this = this;
|
||||
foreach(self, function(v, k) {
|
||||
if (k.charAt(0) == '$') {
|
||||
_this[k] = v;
|
||||
}
|
||||
});
|
||||
};
|
||||
pipeThis.prototype = self.self;
|
||||
return fn.apply(new pipeThis(), args);
|
||||
return fn.apply(self.state, args);
|
||||
};
|
||||
return function(){
|
||||
return fnInvoke;
|
||||
|
|
@ -2883,12 +2873,17 @@ angularDirective("ng-bind-template", function(expression){
|
|||
};
|
||||
});
|
||||
|
||||
var REMOVE_ATTRIBUTES = {
|
||||
'disabled':true,
|
||||
'readonly':true,
|
||||
'checked':true
|
||||
};
|
||||
angularDirective("ng-bind-attr", function(expression){
|
||||
return function(element){
|
||||
this.$onEval(function(){
|
||||
foreach(this.$eval(expression), function(bindExp, key) {
|
||||
var value = compileBindTemplate(bindExp).call(this, element);
|
||||
if (key == 'disabled' && !toBoolean(value)) {
|
||||
if (REMOVE_ATTRIBUTES[lowercase(key)] && !toBoolean(value)) {
|
||||
element.removeAttr('disabled');
|
||||
} else {
|
||||
element.attr(key, value);
|
||||
|
|
@ -3129,7 +3124,7 @@ function valueAccessor(scope, element) {
|
|||
required = required || required === '';
|
||||
if (!validator) throw "Validator named '" + validatorName + "' not found.";
|
||||
function validate(value) {
|
||||
var error = required && !trim(value) ? "Required" : validator({self:scope, scope:{get:scope.$get, set:scope.$set}}, value);
|
||||
var error = required && !trim(value) ? "Required" : validator({state:scope, scope:{get:scope.$get, set:scope.$set}}, value);
|
||||
if (error !== lastError) {
|
||||
elementError(element, NG_VALIDATION_ERROR, error);
|
||||
lastError = error;
|
||||
|
|
@ -3402,7 +3397,7 @@ angularService("$location", function(browser){
|
|||
angularService("$hover", function(browser) {
|
||||
var tooltip, self = this, error, width = 300, arrowWidth = 10;
|
||||
browser.hover(function(element, show){
|
||||
if (show && (error = element.attr('ng-error'))) {
|
||||
if (show && (error = element.attr(NG_EXCEPTION) || element.attr(NG_VALIDATION_ERROR))) {
|
||||
if (!tooltip) {
|
||||
tooltip = {
|
||||
callout: jqLite('<div id="ng-callout"></div>'),
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ var consoleNode,
|
|||
PRIORITY_WATCH = -1000,
|
||||
PRIORITY_LAST = 99999,
|
||||
NOOP = 'noop',
|
||||
NG_ERROR = 'ng-error',
|
||||
NG_EXCEPTION = 'ng-exception',
|
||||
NG_VALIDATION_ERROR = 'ng-validation-error',
|
||||
jQuery = window['jQuery'] || window['$'], // weirdness to make IE happy
|
||||
|
|
@ -259,10 +258,10 @@ function elementError(element, type, error) {
|
|||
}
|
||||
if (error) {
|
||||
element.addClass(type);
|
||||
element.attr(NG_ERROR, error);
|
||||
element.attr(type, error);
|
||||
} else {
|
||||
element.removeClass(type);
|
||||
element.removeAttr(NG_ERROR);
|
||||
element.removeAttr(type);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -80,12 +80,17 @@ angularDirective("ng-bind-template", function(expression){
|
|||
};
|
||||
});
|
||||
|
||||
var REMOVE_ATTRIBUTES = {
|
||||
'disabled':true,
|
||||
'readonly':true,
|
||||
'checked':true
|
||||
};
|
||||
angularDirective("ng-bind-attr", function(expression){
|
||||
return function(element){
|
||||
this.$onEval(function(){
|
||||
foreach(this.$eval(expression), function(bindExp, key) {
|
||||
var value = compileBindTemplate(bindExp).call(this, element);
|
||||
if (key == 'disabled' && !toBoolean(value)) {
|
||||
if (REMOVE_ATTRIBUTES[lowercase(key)] && !toBoolean(value)) {
|
||||
element.removeAttr('disabled');
|
||||
} else {
|
||||
element.attr(key, value);
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ angularService("$location", function(browser){
|
|||
angularService("$hover", function(browser) {
|
||||
var tooltip, self = this, error, width = 300, arrowWidth = 10;
|
||||
browser.hover(function(element, show){
|
||||
if (show && (error = element.attr('ng-error'))) {
|
||||
if (show && (error = element.attr(NG_EXCEPTION) || element.attr(NG_VALIDATION_ERROR))) {
|
||||
if (!tooltip) {
|
||||
tooltip = {
|
||||
callout: jqLite('<div id="ng-callout"></div>'),
|
||||
|
|
|
|||
|
|
@ -299,20 +299,20 @@ BinderTest.prototype.testIfTextBindingThrowsErrorDecorateTheSpan = function(){
|
|||
var span = childNode(doc, 0);
|
||||
assertTrue(span.hasClass('ng-exception'));
|
||||
assertEquals('ErrorMsg1', fromJson(span.text()));
|
||||
assertEquals('"ErrorMsg1"', span.attr('ng-error'));
|
||||
assertEquals('"ErrorMsg1"', span.attr('ng-exception'));
|
||||
|
||||
a.scope.$set('error.throw', function(){throw "MyError";});
|
||||
a.scope.$eval();
|
||||
span = childNode(doc, 0);
|
||||
assertTrue(span.hasClass('ng-exception'));
|
||||
assertTrue(span.text(), span.text().match('MyError') !== null);
|
||||
assertEquals('"MyError"', span.attr('ng-error'));
|
||||
assertEquals('"MyError"', span.attr('ng-exception'));
|
||||
|
||||
a.scope.$set('error.throw', function(){return "ok";});
|
||||
a.scope.$eval();
|
||||
assertFalse(span.hasClass('ng-exception'));
|
||||
assertEquals('ok', span.text());
|
||||
assertEquals(null, span.attr('ng-error'));
|
||||
assertEquals(null, span.attr('ng-exception'));
|
||||
};
|
||||
|
||||
BinderTest.prototype.testIfAttrBindingThrowsErrorDecorateTheAttribute = function(){
|
||||
|
|
@ -322,14 +322,14 @@ BinderTest.prototype.testIfAttrBindingThrowsErrorDecorateTheAttribute = function
|
|||
a.scope.$set('error.throw', function(){throw "ErrorMsg";});
|
||||
a.scope.$eval();
|
||||
assertTrue('ng-exception', doc.hasClass('ng-exception'));
|
||||
assertEquals('"ErrorMsg"', doc.attr('ng-error'));
|
||||
assertEquals('"ErrorMsg"', doc.attr('ng-exception'));
|
||||
assertEquals('before "ErrorMsg" after', doc.attr('attr'));
|
||||
|
||||
a.scope.$set('error.throw', function(){ return 'X';});
|
||||
a.scope.$eval();
|
||||
assertFalse('!ng-exception', doc.hasClass('ng-exception'));
|
||||
assertEquals('before X after', doc.attr('attr'));
|
||||
assertEquals(null, doc.attr('ng-error'));
|
||||
assertEquals(null, doc.attr('ng-exception'));
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -474,7 +474,7 @@ BinderTest.prototype.testActionOnAHrefThrowsError = function(){
|
|||
};
|
||||
var input = c.node;
|
||||
input.click();
|
||||
assertEquals({a:"abc", b:2}, fromJson(input.attr('ng-error')));
|
||||
assertEquals({a:"abc", b:2}, fromJson(input.attr('ng-exception')));
|
||||
assertTrue("should have an error class", input.hasClass('ng-exception'));
|
||||
|
||||
// TODO: I think that exception should never get cleared so this portion of test makes no sense
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ describe('scope/model', function(){
|
|||
var element = jqLite('<div></div>');
|
||||
var scope = createScope();
|
||||
scope.$tryEval('throw "myError"', element);
|
||||
expect(element.attr('ng-error')).toEqual('"myError"'); // errors are jsonified
|
||||
expect(element.attr('ng-exception')).toEqual('"myError"'); // errors are jsonified
|
||||
expect(element.hasClass('ng-exception')).toBeTruthy();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ describe('Validator:asynchronous', function(){
|
|||
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");
|
||||
expect(input.attr('ng-validation-error')).toEqual("myError");
|
||||
scope.$element.remove();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ describe("directives", function(){
|
|||
it('should error on wrong parsing of ng-repeat', function(){
|
||||
var scope = compile('<ul><li ng-repeat="i dont parse"></li></ul>');
|
||||
var log = "";
|
||||
log += element.attr('ng-error') + ';';
|
||||
log += element.attr('ng-exception') + ';';
|
||||
log += element.hasClass('ng-exception') + ';';
|
||||
expect(log).toEqual("\"Expected ng-repeat in form of 'item in collection' but got 'i dont parse'.\";true;");
|
||||
});
|
||||
|
|
|
|||
|
|
@ -54,36 +54,36 @@ describe("input widget", function(){
|
|||
it("should process ng-validation", function(){
|
||||
compile('<input type="text" name="price" value="abc" ng-validate="number"/>');
|
||||
expect(element.hasClass('ng-validation-error')).toBeTruthy();
|
||||
expect(element.attr('ng-error')).toEqual('Not a number');
|
||||
expect(element.attr('ng-validation-error')).toEqual('Not a number');
|
||||
|
||||
scope.$set('price', '123');
|
||||
scope.$eval();
|
||||
expect(element.hasClass('ng-validation-error')).toBeFalsy();
|
||||
expect(element.attr('ng-error')).toBeFalsy();
|
||||
expect(element.attr('ng-validation-error')).toBeFalsy();
|
||||
|
||||
element.val('x');
|
||||
element.trigger('keyup');
|
||||
expect(element.hasClass('ng-validation-error')).toBeTruthy();
|
||||
expect(element.attr('ng-error')).toEqual('Not a number');
|
||||
expect(element.attr('ng-validation-error')).toEqual('Not a number');
|
||||
});
|
||||
|
||||
it("should process ng-required", function(){
|
||||
compile('<input type="text" name="price" ng-required/>');
|
||||
expect(element.hasClass('ng-validation-error')).toBeTruthy();
|
||||
expect(element.attr('ng-error')).toEqual('Required');
|
||||
expect(element.attr('ng-validation-error')).toEqual('Required');
|
||||
|
||||
scope.$set('price', 'xxx');
|
||||
scope.$eval();
|
||||
expect(element.hasClass('ng-validation-error')).toBeFalsy();
|
||||
expect(element.attr('ng-error')).toBeFalsy();
|
||||
expect(element.attr('ng-validation-error')).toBeFalsy();
|
||||
|
||||
element.val('');
|
||||
element.trigger('keyup');
|
||||
expect(element.hasClass('ng-validation-error')).toBeTruthy();
|
||||
expect(element.attr('ng-error')).toEqual('Required');
|
||||
expect(element.attr('ng-validation-error')).toEqual('Required');
|
||||
});
|
||||
|
||||
it("should process ng-required", function() {
|
||||
it("should process ng-required2", function() {
|
||||
compile('<textarea name="name">Misko</textarea>');
|
||||
expect(scope.$get('name')).toEqual("Misko");
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue