Skip to content

Commit 51d3224

Browse files
committed
fix($compile): correct controller instantiation for async directives
This fixes regression introduced by angular#3514 (9c51d50) - this commit is being reverted here and a better fix is included. The regression caused the controller to be instantiated before the isolate scope was initialized. Closes angular#3493 Closes angular#3482 Closes angular#3537 Closes angular#3540
1 parent 1c1a1bc commit 51d3224

File tree

2 files changed

+67
-11
lines changed

2 files changed

+67
-11
lines changed

src/ng/compile.js

+12-11
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,13 @@ function $CompileProvider($provide) {
621621

622622
directiveName = directive.name;
623623

624+
if (directiveValue = directive.controller) {
625+
controllerDirectives = controllerDirectives || {};
626+
assertNoDuplicate("'" + directiveName + "' controller",
627+
controllerDirectives[directiveName], directive, $compileNode);
628+
controllerDirectives[directiveName] = directive;
629+
}
630+
624631
if (directiveValue = directive.transclude) {
625632
assertNoDuplicate('transclusion', transcludeDirective, directive, $compileNode);
626633
transcludeDirective = directive;
@@ -698,13 +705,6 @@ function $CompileProvider($provide) {
698705
}
699706
}
700707

701-
if (!directive.templateUrl && directive.controller) {
702-
controllerDirectives = controllerDirectives || {};
703-
assertNoDuplicate("'" + directiveName + "' controller",
704-
controllerDirectives[directiveName], directive, $compileNode);
705-
controllerDirectives[directiveName] = directive;
706-
}
707-
708708
if (directive.terminal) {
709709
nodeLinkFn.terminal = true;
710710
terminalPriority = Math.max(terminalPriority, directive.priority);
@@ -962,7 +962,7 @@ function $CompileProvider($provide) {
962962
origAsyncDirective = directives.shift(),
963963
// The fact that we have to copy and patch the directive seems wrong!
964964
derivedSyncDirective = extend({}, origAsyncDirective, {
965-
templateUrl: null, transclude: null, scope: null
965+
controller: null, templateUrl: null, transclude: null, scope: null
966966
});
967967

968968
$compileNode.html('');
@@ -1008,9 +1008,10 @@ function $CompileProvider($provide) {
10081008
replaceWith(linkRootElement, jqLite(beforeTemplateLinkNode), linkNode);
10091009
}
10101010

1011-
afterTemplateNodeLinkFn(function() {
1012-
beforeTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, linkNode, $rootElement, controller);
1013-
}, scope, linkNode, $rootElement, controller);
1011+
afterTemplateNodeLinkFn(
1012+
beforeTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, linkNode, $rootElement, controller),
1013+
scope, linkNode, $rootElement, controller
1014+
);
10141015
}
10151016
linkQueue = null;
10161017
}).

test/ng/compileSpec.js

+55
Original file line numberDiff line numberDiff line change
@@ -2258,6 +2258,61 @@ describe('$compile', function() {
22582258
});
22592259

22602260

2261+
it('should instantiate the controller after the isolate scope bindings are initialized (with template)', function () {
2262+
module(function () {
2263+
var Ctrl = function ($scope, log) {
2264+
log('myFoo=' + $scope.myFoo);
2265+
};
2266+
2267+
directive('myDirective', function () {
2268+
return {
2269+
scope: {
2270+
myFoo: "="
2271+
},
2272+
template: '<p>Hello</p>',
2273+
controller: Ctrl
2274+
};
2275+
});
2276+
});
2277+
2278+
inject(function ($templateCache, $compile, $rootScope, log) {
2279+
$rootScope.foo = "bar";
2280+
2281+
element = $compile('<div my-directive my-foo="foo"></div>')($rootScope);
2282+
$rootScope.$apply();
2283+
expect(log).toEqual('myFoo=bar');
2284+
});
2285+
});
2286+
2287+
2288+
it('should instantiate the controller after the isolate scope bindings are initialized (with templateUrl)', function () {
2289+
module(function () {
2290+
var Ctrl = function ($scope, log) {
2291+
log('myFoo=' + $scope.myFoo);
2292+
};
2293+
2294+
directive('myDirective', function () {
2295+
return {
2296+
scope: {
2297+
myFoo: "="
2298+
},
2299+
templateUrl: 'hello.html',
2300+
controller: Ctrl
2301+
};
2302+
});
2303+
});
2304+
2305+
inject(function ($templateCache, $compile, $rootScope, log) {
2306+
$templateCache.put('hello.html', '<p>Hello</p>');
2307+
$rootScope.foo = "bar";
2308+
2309+
element = $compile('<div my-directive my-foo="foo"></div>')($rootScope);
2310+
$rootScope.$apply();
2311+
expect(log).toEqual('myFoo=bar');
2312+
});
2313+
});
2314+
2315+
22612316
it('should instantiate controllers in the parent->child->baby order when nested transluction, templateUrl and ' +
22622317
'replacement are in the mix', function() {
22632318
// similar to the test above, except that we have one more layer of nesting and nested transclusion

0 commit comments

Comments
 (0)