Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 0196730

Browse files
committed
perf($compile): simplifying/refactoring controller loops/methods
1 parent 7a1edda commit 0196730

File tree

1 file changed

+53
-52
lines changed

1 file changed

+53
-52
lines changed

src/ng/compile.js

+53-52
Original file line numberDiff line numberDiff line change
@@ -1671,7 +1671,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
16711671

16721672
if (!directive.templateUrl && directive.controller) {
16731673
directiveValue = directive.controller;
1674-
controllerDirectives = controllerDirectives || {};
1674+
controllerDirectives = controllerDirectives || createMap();
16751675
assertNoDuplicate("'" + directiveName + "' controller",
16761676
controllerDirectives[directiveName], directive, $compileNode);
16771677
controllerDirectives[directiveName] = directive;
@@ -1839,49 +1839,43 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
18391839

18401840

18411841
function getControllers(directiveName, require, $element, elementControllers) {
1842-
var value, retrievalMethod = 'data', optional = false;
1843-
var $searchElement = $element;
1844-
var match;
1845-
if (isString(require)) {
1846-
match = require.match(REQUIRE_PREFIX_REGEXP);
1847-
require = require.substring(match[0].length);
1848-
1849-
if (match[3]) {
1850-
if (match[1]) match[3] = null;
1851-
else match[1] = match[3];
1852-
}
1853-
if (match[1] === '^') {
1854-
retrievalMethod = 'inheritedData';
1855-
} else if (match[1] === '^^') {
1856-
retrievalMethod = 'inheritedData';
1857-
$searchElement = $element.parent();
1858-
}
1859-
if (match[2] === '?') {
1860-
optional = true;
1861-
}
1842+
var i, value;
18621843

1863-
value = null;
1844+
if (typeof require === 'string') {
1845+
var match = require.match(REQUIRE_PREFIX_REGEXP);
1846+
var name = require.substring(match[0].length);
1847+
var type = match[1] || match[3];
18641848

1865-
if (elementControllers && retrievalMethod === 'data') {
1866-
if (value = elementControllers[require]) {
1867-
value = value.instance;
1868-
}
1849+
//If only parents then start at the parent element
1850+
//Otherwise attempt getting the controller from elementControllers to avoid .data
1851+
if (type === '^^') {
1852+
$element = $element.parent();
1853+
} else {
1854+
value = elementControllers && elementControllers[name];
1855+
value = value && value.instance;
18691856
}
1870-
value = value || $searchElement[retrievalMethod]('$' + require + 'Controller');
18711857

1872-
if (!value && !optional) {
1858+
if (!value) {
1859+
var dataName = '$' + name + 'Controller';
1860+
value = type ? $element.inheritedData(dataName) : $element.data(dataName);
1861+
}
1862+
1863+
if (!value && match[2] !== '?') {
18731864
throw $compileMinErr('ctreq',
18741865
"Controller '{0}', required by directive '{1}', can't be found!",
1875-
require, directiveName);
1866+
name, directiveName);
18761867
}
1868+
18771869
return value || null;
1878-
} else if (isArray(require)) {
1879-
value = [];
1880-
forEach(require, function(require) {
1881-
value.push(getControllers(directiveName, require, $element, elementControllers));
1882-
});
18831870
}
1884-
return value;
1871+
1872+
if (isArray(require)) {
1873+
value = new Array(i = require.length);
1874+
while (i--) {
1875+
value[i] = getControllers(directiveName, require[i], $element, elementControllers);
1876+
}
1877+
return value;
1878+
}
18851879
}
18861880

18871881

@@ -1910,32 +1904,37 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
19101904
}
19111905

19121906
if (controllerDirectives) {
1913-
elementControllers = {};
1914-
forEach(controllerDirectives, function(directive) {
1907+
elementControllers = createMap();
1908+
1909+
// For directives with element transclusion the element is a comment,
1910+
// but jQuery .data doesn't support attaching data to comment nodes as it's hard to
1911+
// clean up (http://bugs.jquery.com/ticket/8335).
1912+
// Instead, we save the controllers for the element in a local hash and attach to .data
1913+
// later, once we have the actual element.
1914+
var controllerData = !hasElementTranscludeDirective && $element.data();
1915+
1916+
for (var directiveName in controllerDirectives) {
1917+
var directive = controllerDirectives[directiveName];
1918+
19151919
var locals = {
19161920
$scope: directive === newIsolateScopeDirective || directive.$$isolateScope ? isolateScope : scope,
19171921
$element: $element,
19181922
$attrs: attrs,
19191923
$transclude: transcludeFn
1920-
}, controllerInstance;
1924+
};
19211925

1922-
controller = directive.controller;
1923-
if (controller == '@') {
1924-
controller = attrs[directive.name];
1926+
var directiveController = directive.controller;
1927+
if (directiveController === '@') {
1928+
directiveController = attrs[directive.name];
19251929
}
19261930

1927-
controllerInstance = $controller(controller, locals, true, directive.controllerAs);
1931+
var controllerInstance = $controller(directiveController, locals, true, directive.controllerAs);
19281932

1929-
// For directives with element transclusion the element is a comment,
1930-
// but jQuery .data doesn't support attaching data to comment nodes as it's hard to
1931-
// clean up (http://bugs.jquery.com/ticket/8335).
1932-
// Instead, we save the controllers for the element in a local hash and attach to .data
1933-
// later, once we have the actual element.
19341933
elementControllers[directive.name] = controllerInstance;
1935-
if (!hasElementTranscludeDirective) {
1936-
$element.data('$' + directive.name + 'Controller', controllerInstance.instance);
1934+
if (controllerData) {
1935+
controllerData['$' + directive.name + 'Controller'] = controllerInstance.instance;
19371936
}
1938-
});
1937+
}
19391938
}
19401939

19411940
if (newIsolateScopeDirective) {
@@ -1965,7 +1964,9 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
19651964
bindings, scopeDirective);
19661965
}
19671966
}
1968-
forEach(elementControllers, function(controller) {
1967+
// Initialize the controllers before linking
1968+
for (i in elementControllers) {
1969+
controller = elementControllers[i];
19691970
var result = controller();
19701971
if (result !== controller.instance &&
19711972
controller === controllerForBindings) {
@@ -1975,7 +1976,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
19751976
initializeDirectiveBindings(scope, attrs, result,
19761977
bindings, scopeDirective);
19771978
}
1978-
});
1979+
}
19791980
}
19801981

19811982
// PRELINKING

0 commit comments

Comments
 (0)