mirror of
https://github.com/zhigang1992/angular.js.git
synced 2026-04-17 12:15:56 +08:00
perf($compile): move $$isolateBinding creation to directive factory instead of on each link
This commit is contained in:
@@ -574,6 +574,31 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
||||
// 'on' and be composed of only English letters.
|
||||
var EVENT_HANDLER_ATTR_REGEXP = /^(on[a-z]+|formaction)$/;
|
||||
|
||||
function parseIsolateBindings(scope, directiveName) {
|
||||
var LOCAL_REGEXP = /^\s*([@=&])(\??)\s*(\w*)\s*$/;
|
||||
|
||||
var bindings = {};
|
||||
|
||||
forEach(scope, function(definition, scopeName) {
|
||||
var match = definition.match(LOCAL_REGEXP);
|
||||
|
||||
if (!match) {
|
||||
throw $compileMinErr('iscp',
|
||||
"Invalid isolate scope definition for directive '{0}'." +
|
||||
" Definition: {... {1}: '{2}' ...}",
|
||||
directiveName, scopeName, definition);
|
||||
}
|
||||
|
||||
bindings[scopeName] = {
|
||||
attrName: match[3] || scopeName,
|
||||
mode: match[1],
|
||||
optional: match[2] === '?'
|
||||
};
|
||||
});
|
||||
|
||||
return bindings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name $compileProvider#directive
|
||||
@@ -611,6 +636,9 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
||||
directive.name = directive.name || name;
|
||||
directive.require = directive.require || (directive.controller && directive.name);
|
||||
directive.restrict = directive.restrict || 'EA';
|
||||
if (isObject(directive.scope)) {
|
||||
directive.$$isolateBindings = parseIsolateBindings(directive.scope, directive.name);
|
||||
}
|
||||
directives.push(directive);
|
||||
} catch (e) {
|
||||
$exceptionHandler(e);
|
||||
@@ -1657,16 +1685,14 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
||||
newIsolateScopeDirective.bindToController === true) {
|
||||
isolateBindingContext = isolateScopeController.instance;
|
||||
}
|
||||
forEach(newIsolateScopeDirective.scope, function(definition, scopeName) {
|
||||
var match = definition.match(LOCAL_REGEXP) || [],
|
||||
attrName = match[3] || scopeName,
|
||||
optional = (match[2] == '?'),
|
||||
mode = match[1], // @, =, or &
|
||||
|
||||
forEach(isolateScope.$$isolateBindings = newIsolateScopeDirective.$$isolateBindings, function(definition, scopeName) {
|
||||
var attrName = definition.attrName,
|
||||
optional = definition.optional,
|
||||
mode = definition.mode, // @, =, or &
|
||||
lastValue,
|
||||
parentGet, parentSet, compare;
|
||||
|
||||
isolateScope.$$isolateBindings[scopeName] = mode + attrName;
|
||||
|
||||
switch (mode) {
|
||||
|
||||
case '@':
|
||||
@@ -1721,12 +1747,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
||||
return parentGet(scope, locals);
|
||||
};
|
||||
break;
|
||||
|
||||
default:
|
||||
throw $compileMinErr('iscp',
|
||||
"Invalid isolate scope definition for directive '{0}'." +
|
||||
" Definition: {... {1}: '{2}' ...}",
|
||||
newIsolateScopeDirective.name, scopeName, definition);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ function $RootScopeProvider(){
|
||||
this.$$postDigestQueue = [];
|
||||
this.$$listeners = {};
|
||||
this.$$listenerCount = {};
|
||||
this.$$isolateBindings = {};
|
||||
this.$$isolateBindings = null;
|
||||
this.$$applyAsyncQueue = [];
|
||||
}
|
||||
|
||||
|
||||
@@ -3507,14 +3507,25 @@ describe('$compile', function() {
|
||||
|
||||
expect(typeof componentScope.$$isolateBindings).toBe('object');
|
||||
|
||||
expect(componentScope.$$isolateBindings.attr).toBe('@attr');
|
||||
expect(componentScope.$$isolateBindings.attrAlias).toBe('@attr');
|
||||
expect(componentScope.$$isolateBindings.ref).toBe('=ref');
|
||||
expect(componentScope.$$isolateBindings.refAlias).toBe('=ref');
|
||||
expect(componentScope.$$isolateBindings.reference).toBe('=reference');
|
||||
expect(componentScope.$$isolateBindings.expr).toBe('&expr');
|
||||
expect(componentScope.$$isolateBindings.exprAlias).toBe('&expr');
|
||||
expect(componentScope.$$isolateBindings.attr.mode).toBe('@');
|
||||
expect(componentScope.$$isolateBindings.attr.attrName).toBe('attr');
|
||||
expect(componentScope.$$isolateBindings.attrAlias.attrName).toBe('attr');
|
||||
expect(componentScope.$$isolateBindings.ref.mode).toBe('=');
|
||||
expect(componentScope.$$isolateBindings.ref.attrName).toBe('ref');
|
||||
expect(componentScope.$$isolateBindings.refAlias.attrName).toBe('ref');
|
||||
expect(componentScope.$$isolateBindings.reference.mode).toBe('=');
|
||||
expect(componentScope.$$isolateBindings.reference.attrName).toBe('reference');
|
||||
expect(componentScope.$$isolateBindings.expr.mode).toBe('&');
|
||||
expect(componentScope.$$isolateBindings.expr.attrName).toBe('expr');
|
||||
expect(componentScope.$$isolateBindings.exprAlias.attrName).toBe('expr');
|
||||
|
||||
var firstComponentScope = componentScope,
|
||||
first$$isolateBindings = componentScope.$$isolateBindings;
|
||||
|
||||
dealoc(element);
|
||||
compile('<div><span my-component>');
|
||||
expect(componentScope).not.toBe(firstComponentScope);
|
||||
expect(componentScope.$$isolateBindings).toBe(first$$isolateBindings);
|
||||
}));
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user