mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-25 02:40:24 +00:00
$invalid widget clear on switch change
This commit is contained in:
parent
713307b650
commit
7c49b25548
5 changed files with 80 additions and 8 deletions
53
angular-debug.js
vendored
53
angular-debug.js
vendored
|
|
@ -33,6 +33,7 @@ var consoleNode,
|
|||
PRIORITY_FIRST = -99999,
|
||||
PRIORITY_WATCH = -1000,
|
||||
PRIORITY_LAST = 99999,
|
||||
PRIORITY = {'FIRST': PRIORITY_FIRST, 'LAST': PRIORITY_LAST, 'WATCH':PRIORITY_WATCH},
|
||||
NOOP = 'noop',
|
||||
NG_EXCEPTION = 'ng-exception',
|
||||
NG_VALIDATION_ERROR = 'ng-validation-error',
|
||||
|
|
@ -501,17 +502,34 @@ function toJsonArray(buf, obj, pretty, stack){
|
|||
* bind to a new instance of elements. It also provides a list
|
||||
* of child paths which contain child templates
|
||||
*/
|
||||
function Template() {
|
||||
function Template(priority) {
|
||||
this.paths = [];
|
||||
this.children = [];
|
||||
this.inits = [];
|
||||
this.priority = priority || 0;
|
||||
}
|
||||
|
||||
Template.prototype = {
|
||||
init: function(element, scope) {
|
||||
var inits = {};
|
||||
this.collectInits(element, inits);
|
||||
foreachSorted(inits, function(queue){
|
||||
foreach(queue, function(fn){
|
||||
fn(scope);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
collectInits: function(element, inits) {
|
||||
var queue = inits[this.priority];
|
||||
if (!queue) {
|
||||
inits[this.priority] = queue = [];
|
||||
}
|
||||
element = jqLite(element);
|
||||
foreach(this.inits, function(fn) {
|
||||
scope.$tryEval(fn, element, element);
|
||||
queue.push(function(scope) {
|
||||
scope.$tryEval(fn, element, element);
|
||||
});
|
||||
});
|
||||
|
||||
var i,
|
||||
|
|
@ -520,7 +538,7 @@ Template.prototype = {
|
|||
paths = this.paths,
|
||||
length = paths.length;
|
||||
for (i = 0; i < length; i++) {
|
||||
children[i].init(childNodes[paths[i]], scope);
|
||||
children[i].collectInits(childNodes[paths[i]], inits);
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -575,13 +593,13 @@ Compiler.prototype = {
|
|||
};
|
||||
},
|
||||
|
||||
templatize: function(element){
|
||||
templatize: function(element, priority){
|
||||
var self = this,
|
||||
widget,
|
||||
directiveFns = self.directives,
|
||||
descend = true,
|
||||
directives = true,
|
||||
template = new Template(),
|
||||
template,
|
||||
selfApi = {
|
||||
compile: bind(self, self.compile),
|
||||
comment:function(text) {return jqLite(document.createComment(text));},
|
||||
|
|
@ -590,7 +608,11 @@ Compiler.prototype = {
|
|||
descend: function(value){ if(isDefined(value)) descend = value; return descend;},
|
||||
directives: function(value){ if(isDefined(value)) directives = value; return directives;}
|
||||
};
|
||||
|
||||
priority = element.attr('ng-eval-order') || priority || 0;
|
||||
if (isString(priority)) {
|
||||
priority = PRIORITY[uppercase(priority)] || 0;
|
||||
}
|
||||
template = new Template(priority);
|
||||
eachAttribute(element, function(value, name){
|
||||
if (!widget) {
|
||||
if (widget = self.widgets['@' + name]) {
|
||||
|
|
@ -632,7 +654,7 @@ Compiler.prototype = {
|
|||
// Process non text child nodes
|
||||
if (descend) {
|
||||
eachNode(element, function(child, i){
|
||||
template.addChild(i, self.templatize(child));
|
||||
template.addChild(i, self.templatize(child, priority));
|
||||
});
|
||||
}
|
||||
return template.empty() ? null : template;
|
||||
|
|
@ -3339,6 +3361,8 @@ angularWidget('NG:SWITCH', function ngSwitch(element){
|
|||
element.append(switchCase.element);
|
||||
childScope.$tryEval(switchCase.change, element);
|
||||
switchCase.template(switchCase.element, childScope);
|
||||
if (scope.$invalidWidgets)
|
||||
scope.$invalidWidgets.clearOrphans();
|
||||
childScope.$init();
|
||||
}
|
||||
});
|
||||
|
|
@ -3491,6 +3515,21 @@ angularService("$invalidWidgets", function(){
|
|||
});
|
||||
return count;
|
||||
};
|
||||
invalidWidgets.clearOrphans = function() {
|
||||
for(var i = 0; i < invalidWidgets.length;) {
|
||||
var widget = invalidWidgets[i];
|
||||
if (isOrphan(widget[0])) {
|
||||
invalidWidgets.splice(i, 1);
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
};
|
||||
function isOrphan(widget) {
|
||||
if (widget == window.document) return false;
|
||||
var parent = widget.parentNode;
|
||||
return !parent || isOrphan(parent);
|
||||
}
|
||||
return invalidWidgets;
|
||||
});
|
||||
var browserSingleton;
|
||||
|
|
|
|||
|
|
@ -115,5 +115,20 @@ angularService("$invalidWidgets", function(){
|
|||
});
|
||||
return count;
|
||||
};
|
||||
invalidWidgets.clearOrphans = function() {
|
||||
for(var i = 0; i < invalidWidgets.length;) {
|
||||
var widget = invalidWidgets[i];
|
||||
if (isOrphan(widget[0])) {
|
||||
invalidWidgets.splice(i, 1);
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
};
|
||||
function isOrphan(widget) {
|
||||
if (widget == window.document) return false;
|
||||
var parent = widget.parentNode;
|
||||
return !parent || isOrphan(parent);
|
||||
}
|
||||
return invalidWidgets;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -225,6 +225,8 @@ angularWidget('NG:SWITCH', function ngSwitch(element){
|
|||
element.append(switchCase.element);
|
||||
childScope.$tryEval(switchCase.change, element);
|
||||
switchCase.template(switchCase.element, childScope);
|
||||
if (scope.$invalidWidgets)
|
||||
scope.$invalidWidgets.clearOrphans();
|
||||
childScope.$init();
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -80,11 +80,22 @@ describe("service $invalidWidgets", function(){
|
|||
});
|
||||
|
||||
it("should count number of invalid widgets", function(){
|
||||
var scope = compile('<input name="price" ng-required></input>').$init();
|
||||
var scope = compile('<input name="price" ng-required ng-validate="number"></input>').$init();
|
||||
expect(scope.$invalidWidgets.length).toEqual(1);
|
||||
scope.price = 123;
|
||||
scope.$eval();
|
||||
expect(scope.$invalidWidgets.length).toEqual(0);
|
||||
scope.$element.remove();
|
||||
scope.price = 'abc';
|
||||
scope.$eval();
|
||||
expect(scope.$invalidWidgets.length).toEqual(1);
|
||||
|
||||
jqLite(document.body).append(scope.$element);
|
||||
scope.$invalidWidgets.clearOrphans();
|
||||
expect(scope.$invalidWidgets.length).toEqual(1);
|
||||
|
||||
jqLite(document.body).html('');
|
||||
scope.$invalidWidgets.clearOrphans();
|
||||
expect(scope.$invalidWidgets.length).toEqual(0);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -221,10 +221,15 @@ describe('ng:switch', function(){
|
|||
|
||||
it('should call init on switch', function(){
|
||||
var scope = compile('<ng:switch on="url" change="name=\'works\'"><div ng-switch-when="a">{{name}}</div></ng:include>');
|
||||
var cleared = false;
|
||||
scope.url = 'a';
|
||||
scope.$invalidWidgets = {clearOrphans: function(){
|
||||
cleared = true;
|
||||
}};
|
||||
scope.$init();
|
||||
expect(scope.name).toEqual(undefined);
|
||||
expect(scope.$element.text()).toEqual('works');
|
||||
expect(cleared).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue