diff --git a/src/core/services/compiler/compiler.js b/src/core/services/compiler/compiler.js
index abe73665dd..e5b7bc45a5 100644
--- a/src/core/services/compiler/compiler.js
+++ b/src/core/services/compiler/compiler.js
@@ -436,6 +436,15 @@ function MdCompilerProvider($compileProvider) {
// Create the specified controller instance.
var ctrl = self._createController(options, injectLocals, locals);
+ // Registering extra $destroy listeners should be avoided.
+ // Only register the listener if the controller implements a $onDestroy hook.
+ if (angular.isFunction(ctrl.$onDestroy)) {
+ scope.$on('$destroy', function() {
+ // Call the $onDestroy hook if it's present on the controller.
+ angular.isFunction(ctrl.$onDestroy) && ctrl.$onDestroy();
+ });
+ }
+
// Unique identifier for AngularJS Route ngView controllers.
element.data('$ngControllerController', ctrl);
element.children().data('$ngControllerController', ctrl);
diff --git a/src/core/services/compiler/compiler.spec.js b/src/core/services/compiler/compiler.spec.js
index df5148294d..88b5234dd0 100644
--- a/src/core/services/compiler/compiler.spec.js
+++ b/src/core/services/compiler/compiler.spec.js
@@ -195,7 +195,7 @@ describe('$mdCompiler service', function() {
}
});
});
-
+
function compileAndLink(options) {
var compileData;
@@ -482,4 +482,61 @@ describe('$mdCompiler service', function() {
});
});
+ describe('AngularJS 1.6+ lifecycle hooks', function() {
+ var $mdCompiler, pageScope, $rootScope;
+
+ beforeEach(module('material.core'));
+
+ beforeEach(inject(function($injector) {
+ $mdCompiler = $injector.get('$mdCompiler');
+ $rootScope = $injector.get('$rootScope');
+ pageScope = $rootScope.$new(false);
+ }));
+
+ it('calls $onInit on initialization', function(done) {
+ var passed = false;
+
+ class TestController {
+ $onInit() { passed = true; }
+ }
+
+ var compileResult = $mdCompiler.compile({
+ template: '',
+ controller: TestController,
+ controllerAs: 'vm',
+ bindToController: true
+ });
+
+ compileResult.then(function(compileOutput) {
+ compileOutput.link(pageScope).scope();
+ expect(passed).toBe(true);
+ done();
+ });
+
+ $rootScope.$apply();
+ });
+
+ it('calls $onDestroy on destruction', function(done) {
+ var passed = false;
+
+ class TestController {
+ $onDestroy() { passed = true; }
+ }
+
+ var compileResult = $mdCompiler.compile({
+ template: '',
+ controller: TestController,
+ controllerAs: 'vm',
+ bindToController: true
+ });
+
+ compileResult.then(function(compileOutput) {
+ compileOutput.link(pageScope).scope().$destroy();
+ expect(passed).toBe(true);
+ done();
+ });
+
+ $rootScope.$apply();
+ });
+ });
});