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

Commit 453d74f

Browse files
fix($compile): ensure $doCheck hooks can be defined in the controller constructor
1 parent 6c2f667 commit 453d74f

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
@@ -2506,9 +2539,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
25062539
}
25072540
}
25082541
if (isFunction(controllerInstance.$doCheck)) {
2509-
controllerInstance.$doCheck();
2510-
}
2511-
if (isFunction(controllerInstance.$doCheck)) {
2542+
controllerScope.$watch(function() { controllerInstance.$doCheck(); });
25122543
controllerInstance.$doCheck();
25132544
}
25142545
if (isFunction(controllerInstance.$onDestroy)) {
@@ -3275,11 +3306,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
32753306
}
32763307
});
32773308

3278-
if (isFunction(destination.$doCheck)) {
3279-
var doCheckWatch = scope.$watch(triggerDoCheckHook);
3280-
removeWatchCollection.push(doCheckWatch);
3281-
}
3282-
32833309
function recordChanges(key, currentValue, previousValue) {
32843310
if (isFunction(destination.$onChanges) && currentValue !== previousValue) {
32853311
// If we have not already scheduled the top level onChangesQueue handler then do so now
@@ -3307,10 +3333,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
33073333
changes = undefined;
33083334
}
33093335

3310-
function triggerDoCheckHook() {
3311-
destination.$doCheck();
3312-
}
3313-
33143336
return {
33153337
initialChanges: initialChanges,
33163338
removeWatches: removeWatchCollection.length && function removeWatches() {

test/ng/compileSpec.js

+45
Original file line numberDiff line numberDiff line change
@@ -3872,6 +3872,51 @@ describe('$compile', function() {
38723872
]);
38733873
});
38743874
});
3875+
3876+
it('should work if $doCheck is provided in the constructor', function() {
3877+
var log = [];
3878+
3879+
function TestController() {
3880+
this.$doCheck = function() { log.push('$doCheck'); };
3881+
this.$onChanges = function() { log.push('$onChanges'); };
3882+
this.$onInit = function() { log.push('$onInit'); };
3883+
}
3884+
3885+
angular.module('my', [])
3886+
.component('dcc', {
3887+
controller: TestController,
3888+
bindings: { 'prop1': '<' }
3889+
});
3890+
3891+
module('my');
3892+
inject(function($compile, $rootScope) {
3893+
element = $compile('<dcc prop1="val"></dcc>')($rootScope);
3894+
expect(log).toEqual([
3895+
'$onChanges',
3896+
'$onInit',
3897+
'$doCheck'
3898+
]);
3899+
3900+
// Clear log
3901+
log = [];
3902+
3903+
$rootScope.$apply();
3904+
expect(log).toEqual([
3905+
'$doCheck',
3906+
'$doCheck'
3907+
]);
3908+
3909+
// Clear log
3910+
log = [];
3911+
3912+
$rootScope.$apply('val = 2');
3913+
expect(log).toEqual([
3914+
'$doCheck',
3915+
'$onChanges',
3916+
'$doCheck'
3917+
]);
3918+
});
3919+
});
38753920
});
38763921

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

0 commit comments

Comments
 (0)