Skip to content

Commit fb80c46

Browse files
petebacondarwinNarretz
authored andcommitted
feat($compile): call $ngOnInit on directive controllers after controller construction
This enables option three of angular#13510 (comment) by allowing the creator of directive controllers using ES6 classes to have a hook that is called when the bindings are definitely available. Moreover this will help solve the problem of accessing `require`d controllers from controller instances without resorting to wiring up in a `link` function. See angular#5893
1 parent 3fb809e commit fb80c46

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

src/ng/compile.js

+9-1
Original file line numberDiff line numberDiff line change
@@ -1079,7 +1079,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
10791079
transclude: options.transclude,
10801080
scope: {},
10811081
bindToController: options.bindings || {},
1082-
restrict: 'E'
1082+
restrict: 'E',
1083+
require: options.require
10831084
};
10841085
}
10851086

@@ -2395,6 +2396,13 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
23952396
}
23962397
}
23972398

2399+
// Trigger the `$onInit` method on all controllers that have one
2400+
forEach(elementControllers, function(controller) {
2401+
if (isFunction(controller.instance.$onInit)) {
2402+
controller.instance.$onInit();
2403+
}
2404+
});
2405+
23982406
// PRELINKING
23992407
for (i = 0, ii = preLinkFns.length; i < ii; i++) {
24002408
linkFn = preLinkFns[i];

test/ng/compileSpec.js

+26
Original file line numberDiff line numberDiff line change
@@ -4929,6 +4929,32 @@ describe('$compile', function() {
49294929
});
49304930
});
49314931

4932+
it('should call `controller.$onInit`, if provided after all the controllers have been constructed', function() {
4933+
4934+
function Controller1($element) { this.id = 1; this.element = $element; }
4935+
Controller1.prototype.$onInit = jasmine.createSpy('$onInit').andCallFake(function() {
4936+
expect(this.element.controller('d1').id).toEqual(1);
4937+
expect(this.element.controller('d2').id).toEqual(2);
4938+
});
4939+
4940+
function Controller2($element) { this.id = 2; this.element = $element; }
4941+
Controller2.prototype.$onInit = jasmine.createSpy('$onInit').andCallFake(function() {
4942+
expect(this.element.controller('d1').id).toEqual(1);
4943+
expect(this.element.controller('d2').id).toEqual(2);
4944+
});
4945+
4946+
angular.module('my', [])
4947+
.directive('d1', function() { return { controller: Controller1 }; })
4948+
.directive('d2', function() { return { controller: Controller2 }; });
4949+
4950+
module('my');
4951+
inject(function($compile, $rootScope) {
4952+
element = $compile('<div d1 d2></div>')($rootScope);
4953+
expect(Controller1.prototype.$onInit).toHaveBeenCalledOnce();
4954+
expect(Controller2.prototype.$onInit).toHaveBeenCalledOnce();
4955+
});
4956+
});
4957+
49324958
describe('should not overwrite @-bound property each digest when not present', function() {
49334959
it('when creating new scope', function() {
49344960
module(function($compileProvider) {

0 commit comments

Comments
 (0)