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

Commit 659c424

Browse files
committed
perf($compile): simplifying/refactoring controller loops/methods
1 parent 75bde12 commit 659c424

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
@@ -1787,54 +1787,48 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
17871787

17881788

17891789
function getControllers(directiveName, require, $element, elementControllers) {
1790-
var value, retrievalMethod = 'data', optional = false;
1791-
var $searchElement = $element;
1792-
var match;
1793-
if (isString(require)) {
1794-
match = require.match(REQUIRE_PREFIX_REGEXP);
1795-
require = require.substring(match[0].length);
1796-
1797-
if (match[3]) {
1798-
if (match[1]) match[3] = null;
1799-
else match[1] = match[3];
1800-
}
1801-
if (match[1] === '^') {
1802-
retrievalMethod = 'inheritedData';
1803-
} else if (match[1] === '^^') {
1804-
retrievalMethod = 'inheritedData';
1805-
$searchElement = $element.parent();
1806-
}
1807-
if (match[2] === '?') {
1808-
optional = true;
1809-
}
1790+
var i, value;
18101791

1811-
value = null;
1792+
if (typeof require === 'string') {
1793+
var match = require.match(REQUIRE_PREFIX_REGEXP);
1794+
var name = require.substring(match[0].length);
1795+
var type = match[1] || match[3];
18121796

1813-
if (elementControllers && retrievalMethod === 'data') {
1814-
if (value = elementControllers[require]) {
1815-
value = value.instance;
1816-
}
1797+
//If only parents then start at the parent element
1798+
//Otherwise attempt getting the controller from elementControllers to avoid .data
1799+
if (type === '^^') {
1800+
$element = $element.parent();
1801+
} else {
1802+
value = elementControllers && elementControllers[name];
1803+
value = value && value.instance;
18171804
}
1818-
value = value || $searchElement[retrievalMethod]('$' + require + 'Controller');
18191805

1820-
if (!value && !optional) {
1806+
if (!value) {
1807+
var dataName = '$' + name + 'Controller';
1808+
value = type ? $element.inheritedData(dataName) : $element.data(dataName);
1809+
}
1810+
1811+
if (!value && match[2] !== '?') {
18211812
throw $compileMinErr('ctreq',
18221813
"Controller '{0}', required by directive '{1}', can't be found!",
1823-
require, directiveName);
1814+
name, directiveName);
18241815
}
1816+
18251817
return value || null;
1826-
} else if (isArray(require)) {
1827-
value = [];
1828-
forEach(require, function getControllersEach(require) {
1829-
value.push(getControllers(directiveName, require, $element, elementControllers));
1830-
});
18311818
}
1832-
return value;
1819+
1820+
if (isArray(require)) {
1821+
value = new Array(i = require.length);
1822+
while (i--) {
1823+
value[i] = getControllers(directiveName, require[i], $element, elementControllers);
1824+
}
1825+
return value;
1826+
}
18331827
}
18341828

18351829

18361830
function nodeLinkFn(childLinkFn, scope, linkNode, $rootElement, boundTranscludeFn) {
1837-
var i, ii, linkFn, controller, isolateScope, elementControllers, transcludeFn, $element,
1831+
var i, ii, linkFn, directive, controller, isolateScope, elementControllers, transcludeFn, $element,
18381832
attrs;
18391833

18401834
if (compileNode === linkNode) {
@@ -1859,31 +1853,35 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
18591853
if (controllerDirectives) {
18601854
elementControllers = {};
18611855

1862-
forEach(controllerDirectives, function nodeLinkControllers(directive) {
1856+
// For directives with element transclusion the element is a comment,
1857+
// but jQuery .data doesn't support attaching data to comment nodes as it's hard to
1858+
// clean up (http://bugs.jquery.com/ticket/8335).
1859+
// Instead, we save the controllers for the element in a local hash and attach to .data
1860+
// later, once we have the actual element.
1861+
var controllerData = !hasElementTranscludeDirective && $element.data();
1862+
1863+
for (var directiveName in controllerDirectives) {
1864+
var directive = controllerDirectives[directiveName];
1865+
18631866
var locals = {
18641867
$scope: directive === newIsolateScopeDirective || directive.$$isolateScope ? isolateScope : scope,
18651868
$element: $element,
18661869
$attrs: attrs,
18671870
$transclude: transcludeFn
1868-
}, controllerInstance;
1871+
};
18691872

1870-
controller = directive.controller;
1871-
if (controller == '@') {
1873+
var controller = directive.controller;
1874+
if (controller === '@') {
18721875
controller = attrs[directive.name];
18731876
}
18741877

1875-
controllerInstance = $controller(controller, locals, true, directive.controllerAs);
1878+
var controllerInstance = $controller(controller, locals, true, directive.controllerAs);
18761879

1877-
// For directives with element transclusion the element is a comment,
1878-
// but jQuery .data doesn't support attaching data to comment nodes as it's hard to
1879-
// clean up (http://bugs.jquery.com/ticket/8335).
1880-
// Instead, we save the controllers for the element in a local hash and attach to .data
1881-
// later, once we have the actual element.
18821880
elementControllers[directive.name] = controllerInstance;
1883-
if (!hasElementTranscludeDirective) {
1884-
$element.data('$' + directive.name + 'Controller', controllerInstance.instance);
1881+
if (controllerData) {
1882+
controllerData['$' + directive.name + 'Controller'] = controllerInstance.instance;
18851883
}
1886-
});
1884+
}
18871885
}
18881886

18891887
if (newIsolateScopeDirective) {
@@ -1970,10 +1968,9 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
19701968
});
19711969
}
19721970

1973-
if (elementControllers) {
1974-
forEach(elementControllers, function nodeLinkInitController(controller) {
1975-
controller();
1976-
});
1971+
// Initialize the controllers before linking
1972+
for (i in elementControllers) {
1973+
elementControllers[i]();
19771974
}
19781975

19791976
// PRELINKING

0 commit comments

Comments
 (0)