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

Commit 3010ed4

Browse files
fix($compile): ensure $doCheck hooks can be defined in the controller constructor
Closes #14811
1 parent de59ca7 commit 3010ed4

File tree

2 files changed

+79
-12
lines changed

2 files changed

+79
-12
lines changed

src/ng/compile.js

+34-12
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,39 @@
316316
* they are waiting for their template to load asynchronously and their own compilation and linking has been
317317
* suspended until that occurs.
318318
*
319+
* ** $doCheck example **
320+
*
321+
* This example show how you might use `$doCheck` to customise the equality check of component inputs.
322+
*
323+
* <example name="doCheckExample" module="do-check-module">
324+
* <file name="index.html">
325+
* <div ng-init="items = []">
326+
* <button ng-click="items.push(items.length)">Add Item</button>
327+
* <button ng-click="items = []">Reset Items</button>
328+
* <pre>{{ items }}</pre>
329+
* <test items="items"></test>
330+
* </div>
331+
* </file>
332+
* <file name="app.js">
333+
* angular.module('do-check-module', [])
334+
* .component('test', {
335+
* bindings: { items: '<' },
336+
* template:
337+
* '<pre>{{ $ctrl.log | json }}</pre>',
338+
* controller: function() {
339+
* this.log = [];
340+
*
341+
* this.$doCheck = function() {
342+
* if (this.items_ref !== this.items) { this.log.push('doCheck: items changed'); }
343+
* if (!angular.equals(this.items_clone, this.items)) { this.log.push('doCheck: items mutated'); }
344+
*
345+
* this.items_clone = angular.copy(this.items);
346+
* this.items_ref = this.items;
347+
* };
348+
* }
349+
* });
350+
* </file>
351+
* </example>
319352
*
320353
* #### `require`
321354
* Require another directive and inject its controller as the fourth argument to the linking function. The
@@ -2519,9 +2552,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
25192552
}
25202553
}
25212554
if (isFunction(controllerInstance.$doCheck)) {
2522-
controllerInstance.$doCheck();
2523-
}
2524-
if (isFunction(controllerInstance.$doCheck)) {
2555+
controllerScope.$watch(function() { controllerInstance.$doCheck(); });
25252556
controllerInstance.$doCheck();
25262557
}
25272558
if (isFunction(controllerInstance.$onDestroy)) {
@@ -3282,11 +3313,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
32823313
}
32833314
});
32843315

3285-
if (isFunction(destination.$doCheck)) {
3286-
var doCheckWatch = scope.$watch(triggerDoCheckHook);
3287-
removeWatchCollection.push(doCheckWatch);
3288-
}
3289-
32903316
function recordChanges(key, currentValue, previousValue) {
32913317
if (isFunction(destination.$onChanges) && currentValue !== previousValue) {
32923318
// If we have not already scheduled the top level onChangesQueue handler then do so now
@@ -3314,10 +3340,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
33143340
changes = undefined;
33153341
}
33163342

3317-
function triggerDoCheckHook() {
3318-
destination.$doCheck();
3319-
}
3320-
33213343
return {
33223344
initialChanges: initialChanges,
33233345
removeWatches: removeWatchCollection.length && function removeWatches() {

test/ng/compileSpec.js

+45
Original file line numberDiff line numberDiff line change
@@ -3860,6 +3860,51 @@ describe('$compile', function() {
38603860
]);
38613861
});
38623862
});
3863+
3864+
it('should work if $doCheck is provided in the constructor', function() {
3865+
var log = [];
3866+
3867+
function TestController() {
3868+
this.$doCheck = function() { log.push('$doCheck'); };
3869+
this.$onChanges = function() { log.push('$onChanges'); };
3870+
this.$onInit = function() { log.push('$onInit'); };
3871+
}
3872+
3873+
angular.module('my', [])
3874+
.component('dcc', {
3875+
controller: TestController,
3876+
bindings: { 'prop1': '<' }
3877+
});
3878+
3879+
module('my');
3880+
inject(function($compile, $rootScope) {
3881+
element = $compile('<dcc prop1="val"></dcc>')($rootScope);
3882+
expect(log).toEqual([
3883+
'$onChanges',
3884+
'$onInit',
3885+
'$doCheck'
3886+
]);
3887+
3888+
// Clear log
3889+
log = [];
3890+
3891+
$rootScope.$apply();
3892+
expect(log).toEqual([
3893+
'$doCheck',
3894+
'$doCheck'
3895+
]);
3896+
3897+
// Clear log
3898+
log = [];
3899+
3900+
$rootScope.$apply('val = 2');
3901+
expect(log).toEqual([
3902+
'$doCheck',
3903+
'$onChanges',
3904+
'$doCheck'
3905+
]);
3906+
});
3907+
});
38633908
});
38643909

38653910
describe('$onChanges', function() {

0 commit comments

Comments
 (0)