@@ -1293,6 +1293,14 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
1293
1293
return function publicLinkFn ( scope , cloneConnectFn , options ) {
1294
1294
assertArg ( scope , 'scope' ) ;
1295
1295
1296
+ if ( previousCompileContext && previousCompileContext . needsNewScope ) {
1297
+ // A parent directive did a replace and a directive on this element asked
1298
+ // for transclusion, which caused us to lose a layer of element on which
1299
+ // we could hold the new transclusion scope, so we will create it manually
1300
+ // here.
1301
+ scope = scope . $parent . $new ( ) ;
1302
+ }
1303
+
1296
1304
options = options || { } ;
1297
1305
var parentBoundTranscludeFn = options . parentBoundTranscludeFn ,
1298
1306
transcludeControllers = options . transcludeControllers ,
@@ -1768,7 +1776,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
1768
1776
} else {
1769
1777
$template = jqLite ( jqLiteClone ( compileNode ) ) . contents ( ) ;
1770
1778
$compileNode . empty ( ) ; // clear contents
1771
- childTranscludeFn = compile ( $template , transcludeFn ) ;
1779
+ childTranscludeFn = compile ( $template , transcludeFn , undefined ,
1780
+ undefined , { needsNewScope : directive . $$isolateScope || directive . $$newScope } ) ;
1772
1781
}
1773
1782
}
1774
1783
@@ -1810,8 +1819,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
1810
1819
var templateDirectives = collectDirectives ( compileNode , [ ] , newTemplateAttrs ) ;
1811
1820
var unprocessedDirectives = directives . splice ( i + 1 , directives . length - ( i + 1 ) ) ;
1812
1821
1813
- if ( newIsolateScopeDirective ) {
1814
- markDirectivesAsIsolate ( templateDirectives ) ;
1822
+ if ( newIsolateScopeDirective || newScopeDirective ) {
1823
+ // The original directive caused the current element to be replaced but this element
1824
+ // also needs to have a new scope, so we need to tell the template directives
1825
+ // that they would need to get their scope from further up, if they require transclusion
1826
+ markDirectiveScope ( templateDirectives , newIsolateScopeDirective , newScopeDirective ) ;
1815
1827
}
1816
1828
directives = directives . concat ( templateDirectives ) . concat ( unprocessedDirectives ) ;
1817
1829
mergeTemplateAttributes ( templateAttrs , newTemplateAttrs ) ;
@@ -2096,10 +2108,15 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
2096
2108
}
2097
2109
}
2098
2110
2099
- function markDirectivesAsIsolate ( directives ) {
2100
- // mark all directives as needing isolate scope.
2111
+ // Depending upon the context in which a directive finds itself it might need to have a new isolated
2112
+ // or child scope created. For instance:
2113
+ // * if the directive has been pulled into a template because another directive with a higher priority
2114
+ // asked for element transclusion
2115
+ // * if the directive itself asks for transclusion but it is at the root of a template and the original
2116
+ // element was replaced. See https://github.com/angular/angular.js/issues/12936
2117
+ function markDirectiveScope ( directives , isolateScope , newScope ) {
2101
2118
for ( var j = 0 , jj = directives . length ; j < jj ; j ++ ) {
2102
- directives [ j ] = inherit ( directives [ j ] , { $$isolateScope : true } ) ;
2119
+ directives [ j ] = inherit ( directives [ j ] , { $$isolateScope : isolateScope , $$newScope : newScope } ) ;
2103
2120
}
2104
2121
}
2105
2122
@@ -2246,7 +2263,9 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
2246
2263
var templateDirectives = collectDirectives ( compileNode , [ ] , tempTemplateAttrs ) ;
2247
2264
2248
2265
if ( isObject ( origAsyncDirective . scope ) ) {
2249
- markDirectivesAsIsolate ( templateDirectives ) ;
2266
+ // the original directive that caused the template to be loaded async required
2267
+ // an isolate scope
2268
+ markDirectiveScope ( templateDirectives , true ) ;
2250
2269
}
2251
2270
directives = templateDirectives . concat ( directives ) ;
2252
2271
mergeTemplateAttributes ( tAttrs , tempTemplateAttrs ) ;
0 commit comments