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

Commit c173ca4

Browse files
chirayukIgorMinar
authored andcommitted
fix($compile): correct controller instantiation for async directives
This fixes regression introduced by #3514 (5c56011) - 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 #3493 Closes #3482 Closes #3537 Closes #3540
1 parent 2430347 commit c173ca4

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
@@ -782,6 +782,13 @@ function $CompileProvider($provide) {
782782

783783
directiveName = directive.name;
784784

785+
if (directiveValue = directive.controller) {
786+
controllerDirectives = controllerDirectives || {};
787+
assertNoDuplicate("'" + directiveName + "' controller",
788+
controllerDirectives[directiveName], directive, $compileNode);
789+
controllerDirectives[directiveName] = directive;
790+
}
791+
785792
if (directiveValue = directive.transclude) {
786793
assertNoDuplicate('transclusion', transcludeDirective, directive, $compileNode);
787794
transcludeDirective = directive;
@@ -870,13 +877,6 @@ function $CompileProvider($provide) {
870877
}
871878
}
872879

873-
if (!directive.templateUrl && directive.controller) {
874-
controllerDirectives = controllerDirectives || {};
875-
assertNoDuplicate("'" + directiveName + "' controller",
876-
controllerDirectives[directiveName], directive, $compileNode);
877-
controllerDirectives[directiveName] = directive;
878-
}
879-
880880
if (directive.terminal) {
881881
nodeLinkFn.terminal = true;
882882
terminalPriority = Math.max(terminalPriority, directive.priority);
@@ -1152,7 +1152,7 @@ function $CompileProvider($provide) {
11521152
origAsyncDirective = directives.shift(),
11531153
// The fact that we have to copy and patch the directive seems wrong!
11541154
derivedSyncDirective = extend({}, origAsyncDirective, {
1155-
templateUrl: null, transclude: null, scope: null, replace: null
1155+
controller: null, templateUrl: null, transclude: null, scope: null, replace: null
11561156
}),
11571157
templateUrl = (isFunction(origAsyncDirective.templateUrl))
11581158
? origAsyncDirective.templateUrl($compileNode, tAttrs)
@@ -1208,9 +1208,10 @@ function $CompileProvider($provide) {
12081208
replaceWith(linkRootElement, jqLite(beforeTemplateLinkNode), linkNode);
12091209
}
12101210

1211-
afterTemplateNodeLinkFn(function() {
1212-
beforeTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, linkNode, $rootElement, controller);
1213-
}, scope, linkNode, $rootElement, controller);
1211+
afterTemplateNodeLinkFn(
1212+
beforeTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, linkNode, $rootElement, controller),
1213+
scope, linkNode, $rootElement, controller
1214+
);
12141215
}
12151216
linkQueue = null;
12161217
}).

test/ng/compileSpec.js

+55
Original file line numberDiff line numberDiff line change
@@ -2455,6 +2455,61 @@ describe('$compile', function() {
24552455
});
24562456

24572457

2458+
it('should instantiate the controller after the isolate scope bindings are initialized (with template)', function () {
2459+
module(function () {
2460+
var Ctrl = function ($scope, log) {
2461+
log('myFoo=' + $scope.myFoo);
2462+
};
2463+
2464+
directive('myDirective', function () {
2465+
return {
2466+
scope: {
2467+
myFoo: "="
2468+
},
2469+
template: '<p>Hello</p>',
2470+
controller: Ctrl
2471+
};
2472+
});
2473+
});
2474+
2475+
inject(function ($templateCache, $compile, $rootScope, log) {
2476+
$rootScope.foo = "bar";
2477+
2478+
element = $compile('<div my-directive my-foo="foo"></div>')($rootScope);
2479+
$rootScope.$apply();
2480+
expect(log).toEqual('myFoo=bar');
2481+
});
2482+
});
2483+
2484+
2485+
it('should instantiate the controller after the isolate scope bindings are initialized (with templateUrl)', function () {
2486+
module(function () {
2487+
var Ctrl = function ($scope, log) {
2488+
log('myFoo=' + $scope.myFoo);
2489+
};
2490+
2491+
directive('myDirective', function () {
2492+
return {
2493+
scope: {
2494+
myFoo: "="
2495+
},
2496+
templateUrl: 'hello.html',
2497+
controller: Ctrl
2498+
};
2499+
});
2500+
});
2501+
2502+
inject(function ($templateCache, $compile, $rootScope, log) {
2503+
$templateCache.put('hello.html', '<p>Hello</p>');
2504+
$rootScope.foo = "bar";
2505+
2506+
element = $compile('<div my-directive my-foo="foo"></div>')($rootScope);
2507+
$rootScope.$apply();
2508+
expect(log).toEqual('myFoo=bar');
2509+
});
2510+
});
2511+
2512+
24582513
it('should instantiate controllers in the parent->child->baby order when nested transluction, templateUrl and ' +
24592514
'replacement are in the mix', function() {
24602515
// similar to the test above, except that we have one more layer of nesting and nested transclusion

0 commit comments

Comments
 (0)