feat($compile): backport $doCheck
Backuport ngDoCheck from Angular 2. Closes #14656
This commit is contained in:
committed by
Peter Bacon Darwin
parent
78e1ba1ef9
commit
e235f20cc1
+22
-1
@@ -300,6 +300,12 @@
|
||||
* `changesObj` is a hash whose keys are the names of the bound properties that have changed, and the values are an
|
||||
* object of the form `{ currentValue, previousValue, isFirstChange() }`. Use this hook to trigger updates within a
|
||||
* component such as cloning the bound value to prevent accidental mutation of the outer value.
|
||||
* * `$doCheck()` - Called on each turn of the digest cycle. Provides an opportunity to detect and act on
|
||||
* changes. Any actions that you wish to take in response to the changes that you detect must be
|
||||
* invoked from this hook; implementing this has no effect on when `$onChanges` is called. For example, this hook
|
||||
* could be useful if you wish to perform a deep equality check, or to check a Date object, changes to which would not
|
||||
* be detected by Angular's change detector and thus not trigger `$onChanges`. This hook is invoked with no arguments;
|
||||
* if detecting changes, you must store the previous value(s) for comparison to the current values.
|
||||
* * `$onDestroy()` - Called on a controller when its containing scope is destroyed. Use this hook for releasing
|
||||
* external resources, watches and event handlers. Note that components have their `$onDestroy()` hooks called in
|
||||
* the same order as the `$scope.$broadcast` events are triggered, which is top down. This means that parent
|
||||
@@ -2499,6 +2505,12 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
||||
$exceptionHandler(e);
|
||||
}
|
||||
}
|
||||
if (isFunction(controllerInstance.$doCheck)) {
|
||||
controllerInstance.$doCheck();
|
||||
}
|
||||
if (isFunction(controllerInstance.$doCheck)) {
|
||||
controllerInstance.$doCheck();
|
||||
}
|
||||
if (isFunction(controllerInstance.$onDestroy)) {
|
||||
controllerScope.$on('$destroy', function callOnDestroyHook() {
|
||||
controllerInstance.$onDestroy();
|
||||
@@ -3151,7 +3163,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
||||
forEach(bindings, function initializeBinding(definition, scopeName) {
|
||||
var attrName = definition.attrName,
|
||||
optional = definition.optional,
|
||||
mode = definition.mode, // @, =, or &
|
||||
mode = definition.mode, // @, =, <, or &
|
||||
lastValue,
|
||||
parentGet, parentSet, compare, removeWatch;
|
||||
|
||||
@@ -3263,6 +3275,11 @@ 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
|
||||
@@ -3290,6 +3307,10 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
||||
changes = undefined;
|
||||
}
|
||||
|
||||
function triggerDoCheckHook() {
|
||||
destination.$doCheck();
|
||||
}
|
||||
|
||||
return {
|
||||
initialChanges: initialChanges,
|
||||
removeWatches: removeWatchCollection.length && function removeWatches() {
|
||||
|
||||
@@ -3828,6 +3828,51 @@ describe('$compile', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('$doCheck', function() {
|
||||
it('should call `$doCheck`, if provided, for each digest cycle, after $onChanges and $onInit', function() {
|
||||
var log = [];
|
||||
|
||||
function TestController() { }
|
||||
TestController.prototype.$doCheck = function() { log.push('$doCheck'); };
|
||||
TestController.prototype.$onChanges = function() { log.push('$onChanges'); };
|
||||
TestController.prototype.$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