fix($compile): ensure $doCheck hooks can be defined in the controller constructor
Closes #14811
This commit is contained in:
+34
-12
@@ -316,6 +316,39 @@
|
||||
* they are waiting for their template to load asynchronously and their own compilation and linking has been
|
||||
* suspended until that occurs.
|
||||
*
|
||||
* ** $doCheck example **
|
||||
*
|
||||
* This example show how you might use `$doCheck` to customise the equality check of component inputs.
|
||||
*
|
||||
* <example name="doCheckExample" module="do-check-module">
|
||||
* <file name="index.html">
|
||||
* <div ng-init="items = []">
|
||||
* <button ng-click="items.push(items.length)">Add Item</button>
|
||||
* <button ng-click="items = []">Reset Items</button>
|
||||
* <pre>{{ items }}</pre>
|
||||
* <test items="items"></test>
|
||||
* </div>
|
||||
* </file>
|
||||
* <file name="app.js">
|
||||
* angular.module('do-check-module', [])
|
||||
* .component('test', {
|
||||
* bindings: { items: '<' },
|
||||
* template:
|
||||
* '<pre>{{ $ctrl.log | json }}</pre>',
|
||||
* controller: function() {
|
||||
* this.log = [];
|
||||
*
|
||||
* this.$doCheck = function() {
|
||||
* if (this.items_ref !== this.items) { this.log.push('doCheck: items changed'); }
|
||||
* if (!angular.equals(this.items_clone, this.items)) { this.log.push('doCheck: items mutated'); }
|
||||
*
|
||||
* this.items_clone = angular.copy(this.items);
|
||||
* this.items_ref = this.items;
|
||||
* };
|
||||
* }
|
||||
* });
|
||||
* </file>
|
||||
* </example>
|
||||
*
|
||||
* #### `require`
|
||||
* Require another directive and inject its controller as the fourth argument to the linking function. The
|
||||
@@ -2506,9 +2539,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
||||
}
|
||||
}
|
||||
if (isFunction(controllerInstance.$doCheck)) {
|
||||
controllerInstance.$doCheck();
|
||||
}
|
||||
if (isFunction(controllerInstance.$doCheck)) {
|
||||
controllerScope.$watch(function() { controllerInstance.$doCheck(); });
|
||||
controllerInstance.$doCheck();
|
||||
}
|
||||
if (isFunction(controllerInstance.$onDestroy)) {
|
||||
@@ -3275,11 +3306,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
||||
}
|
||||
});
|
||||
|
||||
if (isFunction(destination.$doCheck)) {
|
||||
var doCheckWatch = scope.$watch(triggerDoCheckHook);
|
||||
removeWatchCollection.push(doCheckWatch);
|
||||
}
|
||||
|
||||
function recordChanges(key, currentValue, previousValue) {
|
||||
if (isFunction(destination.$onChanges) && currentValue !== previousValue) {
|
||||
// If we have not already scheduled the top level onChangesQueue handler then do so now
|
||||
@@ -3307,10 +3333,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
||||
changes = undefined;
|
||||
}
|
||||
|
||||
function triggerDoCheckHook() {
|
||||
destination.$doCheck();
|
||||
}
|
||||
|
||||
return {
|
||||
initialChanges: initialChanges,
|
||||
removeWatches: removeWatchCollection.length && function removeWatches() {
|
||||
|
||||
@@ -3872,6 +3872,51 @@ describe('$compile', function() {
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
it('should work if $doCheck is provided in the constructor', function() {
|
||||
var log = [];
|
||||
|
||||
function TestController() {
|
||||
this.$doCheck = function() { log.push('$doCheck'); };
|
||||
this.$onChanges = function() { log.push('$onChanges'); };
|
||||
this.$onInit = function() { log.push('$onInit'); };
|
||||
}
|
||||
|
||||
angular.module('my', [])
|
||||
.component('dcc', {
|
||||
controller: TestController,
|
||||
bindings: { 'prop1': '<' }
|
||||
});
|
||||
|
||||
module('my');
|
||||
inject(function($compile, $rootScope) {
|
||||
element = $compile('<dcc prop1="val"></dcc>')($rootScope);
|
||||
expect(log).toEqual([
|
||||
'$onChanges',
|
||||
'$onInit',
|
||||
'$doCheck'
|
||||
]);
|
||||
|
||||
// Clear log
|
||||
log = [];
|
||||
|
||||
$rootScope.$apply();
|
||||
expect(log).toEqual([
|
||||
'$doCheck',
|
||||
'$doCheck'
|
||||
]);
|
||||
|
||||
// Clear log
|
||||
log = [];
|
||||
|
||||
$rootScope.$apply('val = 2');
|
||||
expect(log).toEqual([
|
||||
'$doCheck',
|
||||
'$onChanges',
|
||||
'$doCheck'
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('$onChanges', function() {
|
||||
|
||||
Reference in New Issue
Block a user