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

Commit a471d6f

Browse files
committed
perf($compile): simplifying/refactoring controller loops/methods
1 parent 0487558 commit a471d6f

File tree

1 file changed

+49
-52
lines changed

1 file changed

+49
-52
lines changed

src/ng/compile.js

Lines changed: 49 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1731,54 +1731,48 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
17311731

17321732

17331733
function getControllers(directiveName, require, $element, elementControllers) {
1734-
var value, retrievalMethod = 'data', optional = false;
1735-
var $searchElement = $element;
1736-
var match;
1737-
if (isString(require)) {
1738-
match = require.match(REQUIRE_PREFIX_REGEXP);
1739-
require = require.substring(match[0].length);
1740-
1741-
if (match[3]) {
1742-
if (match[1]) match[3] = null;
1743-
else match[1] = match[3];
1744-
}
1745-
if (match[1] === '^') {
1746-
retrievalMethod = 'inheritedData';
1747-
} else if (match[1] === '^^') {
1748-
retrievalMethod = 'inheritedData';
1749-
$searchElement = $element.parent();
1750-
}
1751-
if (match[2] === '?') {
1752-
optional = true;
1753-
}
1734+
var i, value;
17541735

1755-
value = null;
1736+
if (typeof require === 'string') {
1737+
var match = require.match(REQUIRE_PREFIX_REGEXP);
1738+
var name = require.substring(match[0].length);
1739+
var type = match[1] || match[3];
17561740

1757-
if (elementControllers && retrievalMethod === 'data') {
1758-
if (value = elementControllers[require]) {
1759-
value = value.instance;
1760-
}
1741+
//If only parents then start at the parent element
1742+
//Otherwise attempt getting the controller from elementControllers to avoid .data
1743+
if (type === '^^') {
1744+
$element = $element.parent();
1745+
} else {
1746+
value = elementControllers && elementControllers[name];
1747+
value = value && value.instance;
17611748
}
1762-
value = value || $searchElement[retrievalMethod]('$' + require + 'Controller');
17631749

1764-
if (!value && !optional) {
1750+
if (!value) {
1751+
var dataName = '$' + name + 'Controller';
1752+
value = type ? $element.inheritedData(dataName) : $element.data(dataName);
1753+
}
1754+
1755+
if (!value && match[2] !== '?') {
17651756
throw $compileMinErr('ctreq',
17661757
"Controller '{0}', required by directive '{1}', can't be found!",
1767-
require, directiveName);
1758+
name, directiveName);
17681759
}
1760+
17691761
return value || null;
1770-
} else if (isArray(require)) {
1771-
value = [];
1772-
forEach(require, function getControllersEach(require) {
1773-
value.push(getControllers(directiveName, require, $element, elementControllers));
1774-
});
17751762
}
1776-
return value;
1763+
1764+
if (isArray(require)) {
1765+
value = new Array(i = require.length);
1766+
while (i--) {
1767+
value[i] = getControllers(directiveName, require[i], $element, elementControllers);
1768+
}
1769+
return value;
1770+
}
17771771
}
17781772

17791773

17801774
function nodeLinkFn(childLinkFn, scope, linkNode, $rootElement, boundTranscludeFn) {
1781-
var i, ii, linkFn, controller, isolateScope, elementControllers, transcludeFn, $element,
1775+
var i, ii, linkFn, directive, controller, isolateScope, elementControllers, transcludeFn, $element,
17821776
attrs;
17831777

17841778
if (compileNode === linkNode) {
@@ -1797,31 +1791,35 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
17971791
if (controllerDirectives) {
17981792
elementControllers = {};
17991793

1800-
forEach(controllerDirectives, function nodeLinkControllers(directive) {
1794+
// For directives with element transclusion the element is a comment,
1795+
// but jQuery .data doesn't support attaching data to comment nodes as it's hard to
1796+
// clean up (http://bugs.jquery.com/ticket/8335).
1797+
// Instead, we save the controllers for the element in a local hash and attach to .data
1798+
// later, once we have the actual element.
1799+
var controllerData = !hasElementTranscludeDirective && $element.data();
1800+
1801+
for (var directiveName in controllerDirectives) {
1802+
var directive = controllerDirectives[directiveName];
1803+
18011804
var locals = {
18021805
$scope: directive === newIsolateScopeDirective || directive.$$isolateScope ? isolateScope : scope,
18031806
$element: $element,
18041807
$attrs: attrs,
18051808
$transclude: transcludeFn
1806-
}, controllerInstance;
1809+
};
18071810

1808-
controller = directive.controller;
1809-
if (controller == '@') {
1811+
var controller = directive.controller;
1812+
if (controller === '@') {
18101813
controller = attrs[directive.name];
18111814
}
18121815

1813-
controllerInstance = $controller(controller, locals, true, directive.controllerAs);
1816+
var controllerInstance = $controller(controller, locals, true, directive.controllerAs);
18141817

1815-
// For directives with element transclusion the element is a comment,
1816-
// but jQuery .data doesn't support attaching data to comment nodes as it's hard to
1817-
// clean up (http://bugs.jquery.com/ticket/8335).
1818-
// Instead, we save the controllers for the element in a local hash and attach to .data
1819-
// later, once we have the actual element.
18201818
elementControllers[directive.name] = controllerInstance;
1821-
if (!hasElementTranscludeDirective) {
1822-
$element.data('$' + directive.name + 'Controller', controllerInstance.instance);
1819+
if (controllerData) {
1820+
controllerData['$' + directive.name + 'Controller'] = controllerInstance.instance;
18231821
}
1824-
});
1822+
}
18251823
}
18261824

18271825
if (newIsolateScopeDirective) {
@@ -1908,10 +1906,9 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
19081906
});
19091907
}
19101908

1911-
if (elementControllers) {
1912-
forEach(elementControllers, function nodeLinkInitController(controller) {
1913-
controller();
1914-
});
1909+
// Initialize the controllers before linking
1910+
for (i in elementControllers) {
1911+
elementControllers[i]();
19151912
}
19161913

19171914
// PRELINKING

0 commit comments

Comments
 (0)