@@ -1671,7 +1671,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
1671
1671
1672
1672
if ( ! directive . templateUrl && directive . controller ) {
1673
1673
directiveValue = directive . controller ;
1674
- controllerDirectives = controllerDirectives || { } ;
1674
+ controllerDirectives = controllerDirectives || createMap ( ) ;
1675
1675
assertNoDuplicate ( "'" + directiveName + "' controller" ,
1676
1676
controllerDirectives [ directiveName ] , directive , $compileNode ) ;
1677
1677
controllerDirectives [ directiveName ] = directive ;
@@ -1839,49 +1839,43 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
1839
1839
1840
1840
1841
1841
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 ;
1862
1843
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 ] ;
1864
1848
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 ;
1869
1856
}
1870
- value = value || $searchElement [ retrievalMethod ] ( '$' + require + 'Controller' ) ;
1871
1857
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 ] !== '?' ) {
1873
1864
throw $compileMinErr ( 'ctreq' ,
1874
1865
"Controller '{0}', required by directive '{1}', can't be found!" ,
1875
- require , directiveName ) ;
1866
+ name , directiveName ) ;
1876
1867
}
1868
+
1877
1869
return value || null ;
1878
- } else if ( isArray ( require ) ) {
1879
- value = [ ] ;
1880
- forEach ( require , function ( require ) {
1881
- value . push ( getControllers ( directiveName , require , $element , elementControllers ) ) ;
1882
- } ) ;
1883
1870
}
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
+ }
1885
1879
}
1886
1880
1887
1881
@@ -1910,32 +1904,37 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
1910
1904
}
1911
1905
1912
1906
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
+
1915
1919
var locals = {
1916
1920
$scope : directive === newIsolateScopeDirective || directive . $$isolateScope ? isolateScope : scope ,
1917
1921
$element : $element ,
1918
1922
$attrs : attrs ,
1919
1923
$transclude : transcludeFn
1920
- } , controllerInstance ;
1924
+ } ;
1921
1925
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 ] ;
1925
1929
}
1926
1930
1927
- controllerInstance = $controller ( controller , locals , true , directive . controllerAs ) ;
1931
+ var controllerInstance = $controller ( directiveController , locals , true , directive . controllerAs ) ;
1928
1932
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.
1934
1933
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 ;
1937
1936
}
1938
- } ) ;
1937
+ }
1939
1938
}
1940
1939
1941
1940
if ( newIsolateScopeDirective ) {
@@ -1965,7 +1964,9 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
1965
1964
bindings , scopeDirective ) ;
1966
1965
}
1967
1966
}
1968
- forEach ( elementControllers , function ( controller ) {
1967
+ // Initialize the controllers before linking
1968
+ for ( i in elementControllers ) {
1969
+ controller = elementControllers [ i ] ;
1969
1970
var result = controller ( ) ;
1970
1971
if ( result !== controller . instance &&
1971
1972
controller === controllerForBindings ) {
@@ -1975,7 +1976,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
1975
1976
initializeDirectiveBindings ( scope , attrs , result ,
1976
1977
bindings , scopeDirective ) ;
1977
1978
}
1978
- } ) ;
1979
+ }
1979
1980
}
1980
1981
1981
1982
// PRELINKING
0 commit comments